Skip to content

Conversation

zuercher
Copy link
Member

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

…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>
@zuercher zuercher requested a review from brian-pane July 30, 2018 22:44
zuercher added 2 commits July 30, 2018 16:03
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
Signed-off-by: Stephan Zuercher <stephan@turbinelabs.io>
brian-pane
brian-pane previously approved these changes Jul 31, 2018
@@ -52,13 +51,13 @@ bool BinaryProtocolImpl::readMessageBegin(Buffer::Instance& buffer, std::string&
buffer.drain(8);

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));
Copy link
Contributor

Choose a reason for hiding this comment

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

[minor] The cast ideally should be to const char* rather than char*.

Copy link
Member

@rgs1 rgs1 Aug 2, 2018

Choose a reason for hiding this comment

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

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>
@zuercher
Copy link
Member Author

zuercher commented Aug 1, 2018

@brian-pane ptal

brian-pane
brian-pane previously approved these changes Aug 1, 2018
@htuch htuch self-assigned this Aug 1, 2018
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

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());
Copy link
Member

Choose a reason for hiding this comment

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

Can you comment on how this is known to be true?

Copy link
Member Author

Choose a reason for hiding this comment

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

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()) {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Prefer to invert the logic here.

ENVOY_LOG(debug, "thrift: need more data for {} transport start", transport_->name());
buffer_underflow = true;
return ThriftFilters::FilterStatus::Continue;
}
ENVOY_LOG(debug, "thrift: {} transport started", transport_->name());

if (metadata_->hasProtocol()) {
Copy link
Member

Choose a reason for hiding this comment

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

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()) {
Copy link
Member

Choose a reason for hiding this comment

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

Is the map inherently ordered?

Copy link
Member Author

Choose a reason for hiding this comment

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

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 {
Copy link
Member

Choose a reason for hiding this comment

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

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

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.

Copy link
Member

Choose a reason for hiding this comment

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

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

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?

Copy link
Member

Choose a reason for hiding this comment

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

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>
Copy link
Member

@rgs1 rgs1 left a comment

Choose a reason for hiding this comment

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

I see test/extensions/filters/network/thrift_proxy/tmp as part of the first commit, did that get in by accident?

htuch
htuch previously approved these changes Aug 3, 2018
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

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 {
Copy link
Member

Choose a reason for hiding this comment

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

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>
@zuercher
Copy link
Member Author

zuercher commented Aug 6, 2018

Added a todo, removed the stray file, and merged master.

@htuch htuch merged commit b14dee5 into envoyproxy:master Aug 7, 2018
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.

5 participants