thrift_proxy: introduce MessageMetadata to track message headers and other metadata#3991
Conversation
…other metadata In advance of implementing the header transport and "ttwitter" protocol, refactor the message metadata (method name, message type, sequence id) into a metadata object. The MessageMetadata also tracks the protocol (provided by the header transport) and app exception data for exceptions triggered by the transport before the message begins. *Risk Level*: low *Testing*: existing tests *Docs Changes*: n/a *Release Notes*: n/a Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
|
|
||
| if (name_len > 0) { | ||
| name.assign(std::string(static_cast<char*>(buffer.linearize(name_len)), name_len)); | ||
| metadata.setMethodName(std::string(static_cast<char*>(buffer.linearize(name_len)), name_len)); |
There was a problem hiding this comment.
[minor] The cast ideally should be to const char* rather than char*.
There was a problem hiding this comment.
should there be a check for name_len's max value? Otherwise an ill formed message could trigger big allocations... Or is buffer.length() checked for max length somewhere else? Even so, should we check for name_len's max here?
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
|
@brian-pane ptal |
htuch
left a comment
There was a problem hiding this comment.
Looks good. A few questions/nits; general plea for small PRs (and for major cleanups, to make them as mechanical as possible). I know that's not always pragmatic, but where plausible.
| proto.writeMessageBegin(buffer, method_name_, ThriftProxy::MessageType::Exception, seq_id_); | ||
| void AppException::encode(MessageMetadata& metadata, ThriftProxy::Protocol& proto, | ||
| Buffer::Instance& buffer) const { | ||
| ASSERT(metadata.hasMethodName()); |
There was a problem hiding this comment.
Can you comment on how this is known to be true?
There was a problem hiding this comment.
Roughly because of the locations where the class is instantiated, but I'll need it to handle their absence, so I'll just add that.
| return; | ||
| } catch (const AppException& ex) { | ||
| ENVOY_LOG(error, "thrift application exception: {}", ex.what()); | ||
| if (!rpcs_.empty()) { |
There was a problem hiding this comment.
Nit: Prefer to invert the logic here.
| } | ||
| ENVOY_LOG(debug, "thrift: {} transport started", transport_->name()); | ||
|
|
||
| if (metadata_->hasProtocol()) { |
There was a problem hiding this comment.
This looks like a behavioral change; ideally we would split that out from the refactor around metadata that is happening.
| } | ||
|
|
||
| for (auto i = headers_.begin(), j = rhs.headers_.begin(); i != headers_.end(); ++i, ++j) { | ||
| if (i->key() != j->key() || i->value() != j->value()) { |
There was a problem hiding this comment.
At this point it is. I'll discuss more in the question about HeaderMap below.
| /* | ||
| * HeaderMap contains Thrift transport and/or protocol-level headers. | ||
| */ | ||
| class HeaderMap { |
There was a problem hiding this comment.
Why do we need a new HeaderMap abstraction? Could we reuse the existing HTTP one via an adapter or just use a limited surface of its APIs?
There was a problem hiding this comment.
I considered using the Http::HeaderMap. I like the idea of reusing LowerCaseString and HeaderEntryImpl and it's memory management. I balked because it seems likely that most of the 70-odd inline headers will never see use in Thrift. (The non-inline headers are stored in a list, as in the local implementation). I suppose using the Http::HeaderMap will make my life easier when I add logging, since that API takes them. I'll have another look at reusing it.
There was a problem hiding this comment.
FWIW, at some point I would like to make the inline headers that the HeaderMapImpl supports runtime configurable. I think this is possible with some work. Obviously not suggesting you do that, but I thought I would throw that out there. I think that's potentially interesting when private filters want to add extra inline headers and/or we would like to prune some of the inline headers that might not be used in all installations.
There was a problem hiding this comment.
That would be awesome.
@htuch do you mind if I leave this as-is for now and reconsider it when we're actually able to use headers for routing?
There was a problem hiding this comment.
Yeah, but if you could either put in a TODO or file an issue to track this it'd be great, whatever you think is appropriate.
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
rgs1
left a comment
There was a problem hiding this comment.
I see test/extensions/filters/network/thrift_proxy/tmp as part of the first commit, did that get in by accident?
htuch
left a comment
There was a problem hiding this comment.
Can you take a look at the merge conflict? I think this looks good to go otherwise based on surface analysis.
| /* | ||
| * HeaderMap contains Thrift transport and/or protocol-level headers. | ||
| */ | ||
| class HeaderMap { |
There was a problem hiding this comment.
Yeah, but if you could either put in a TODO or file an issue to track this it'd be great, whatever you think is appropriate.
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
|
Added a todo, removed the stray file, and merged master. |
In advance of implementing the header transport and "ttwitter" protocol, refactor
the message metadata (method name, message type, sequence id) into a metadata object.
The MessageMetadata also tracks the protocol (provided by the header transport) and
app exception data for exceptions triggered by the transport before the message begins.
Risk Level: low
Testing: existing tests
Docs Changes: n/a
Release Notes: n/a
Signed-off-by: Stephan Zuercher stephan@turbinelabs.io