Skip to content

[filter state]: make jsonConvert no throw#18863

Merged
lizan merged 6 commits intoenvoyproxy:mainfrom
chaoqin-li1123:json_exception
Nov 17, 2021
Merged

[filter state]: make jsonConvert no throw#18863
lizan merged 6 commits intoenvoyproxy:mainfrom
chaoqin-li1123:json_exception

Conversation

@chaoqin-li1123
Copy link
Copy Markdown
Contributor

Commit Message: Currently FilterStateFormatter::formatValue is converting ProtobufTypes::Message to ProtobufWkt::Value through intermediate json string format, which is not efficient and may throw exception in data plane. Add serializeAsProtoValue virtual method to do the conversion directly.
Additional Description: NA
Risk Level: low
Testing: NA
Docs Changes: NA
Release Notes: NA

@chaoqin-li1123 chaoqin-li1123 requested a review from lizan as a code owner November 2, 2021 14:40
@asraa
Copy link
Copy Markdown
Contributor

asraa commented Nov 3, 2021

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #18863 (comment) was created by @asraa.

see: more, trace.

@yanavlasov yanavlasov self-assigned this Nov 3, 2021
Comment on lines 68 to 72
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic still leave possibility for throwing an exception from MessageToJsonString. and it is changing the behavior, ProtobufWkt::Value is proto representation of JSON itself, so the JSON shouldn't set as string.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is ok if we define serializeAsProtoValue in all the places where serializeAsProto is defined.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC MessageToJsonString is doesn't throw.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just keep existing behavior? We can catch those exceptions and turn into null (theoretically they can throw but not realistically). This is an extension point so we never cover all places.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we plan to remove all the exceptions from worker thread(#14320). And the current behavior that covert a MessagePtr to a protobuf::val through intermediate json string format doesn't seems desirable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just change the protobuf utility to not throw exceptions for those are used in worker thread. We should keep current behavior, a JSON string in ProtobufWkt::Value is not desired at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why we need to provide a default implementation here is that serializeAsProto is not virtual and return nullptr by default. It is difficult to change the utility function jsonConvertValue which have a deep call stack and throw from multiple places, this requires changing the function signature of a few functions which is used frequently in the code base. From my understanding, if we override serializeAsProtoVal for all the classes whose serializeAsProto is being override, that wouldn't change the behavior in the current code base. we can leave comment here to remind the developer to override the serializeAsProtoVal function whenever they override the serializeAsProto.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an alternative, we can keep an extra non-throw version of jsonConvertValue without changing the current function signature, which do you prefer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The former solution avoid converting to json and back to proto val, which is good for performance, but as you said, would change behavior when user define their serializeAsProto method without defining serializeAsProtoVal.

Copy link
Copy Markdown
Contributor

@yanavlasov yanavlasov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/wait

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this function should return nullptr (and return ProtobufWkt::Value by pointer_, the same as the serializeAsProto(). Then it makes the discussion below obsolete.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How shall we handle the nullptr in formatValue? Shall we return a ProtobufWkt::NULL_VALUE for formatting?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not quite right. You actually need to recreate the envoy::extensions::filters::http::grpc_stats::v3::FilterObject as a Value proto. It is not hard since it just has two uint64 fields. The code would look something like this:

::ProtobufWkt::Value value;
auto *struct_value = value.mutable_struct_value();
::ProtobufWkt::Value::Value string_value;
string_value.set_string_value(absl::StrCat(request_message_count));
(*struct_value->mutable_fields())["request_message_count"] = string_value;

// same for the response_message_count

Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
@chaoqin-li1123 chaoqin-li1123 changed the title [filter state]: covert filter state object to ProtobufWkt::Value directly [filter state]: make jsonConvert no throw Nov 12, 2021
@chaoqin-li1123
Copy link
Copy Markdown
Contributor Author

./retest

@chaoqin-li1123
Copy link
Copy Markdown
Contributor Author

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #18863 (comment) was created by @chaoqin-li1123.

see: more, trace.

lizan
lizan previously approved these changes Nov 12, 2021
yanavlasov
yanavlasov previously approved these changes Nov 12, 2021
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
@chaoqin-li1123 chaoqin-li1123 dismissed stale reviews from yanavlasov and lizan via f58dacd November 12, 2021 21:49
chaoqin-li1123 added 3 commits November 12, 2021 22:02
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
@chaoqin-li1123
Copy link
Copy Markdown
Contributor Author

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #18863 (comment) was created by @chaoqin-li1123.

see: more, trace.

@lizan lizan merged commit b610fba into envoyproxy:main Nov 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants