Skip to content

stats: Make an object for the FIlesystem (Filesystem::Instance) to hold the stats counters.#5031

Merged
mattklein123 merged 16 commits intoenvoyproxy:masterfrom
jmarantz:filesystem-stats
Nov 26, 2018
Merged

stats: Make an object for the FIlesystem (Filesystem::Instance) to hold the stats counters.#5031
mattklein123 merged 16 commits intoenvoyproxy:masterfrom
jmarantz:filesystem-stats

Conversation

@jmarantz
Copy link
Contributor

Description: Currently, stats counters/gauges are looked up every time a FileImpl is created. This change factors that out, introducing a Filesystem::Instance to hold the stats objects.

This is important for SymbolTables because lookups from string-literals take a lock, and we don't want to take locks while processing requests.
Risk Level: low
Testing: //test/...
Docs Changes:
Release Notes:

… stats counters in there.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@jmarantz
Copy link
Contributor Author

I think this is failing CI because of an API change to RawConnectionDriver, which now requires a Stats::Store, and this requires changing echo2_integration_test.cc in https://github.com/envoyproxy/envoy-filter-example . I guess that to avoid breaking any build at any time I have to issue two small PRs first:

  1. change RawConnectionDriver to take an optional stat_store object and ignore it
  2. change echo2_integration_test.cc to pass in a Stat::Store which it can get from BaseIntegrationTest via test_server_.stats().

A variation on this is to have BaseIntegrationTest provide a method for building a RawConnectionDriverPtr -- so that it can provide any other context required in the future. That feels a little nicer because I think it means doing this two-repo-PR dance a little less in the future, should more context be required. My concern is that this might be going against the design goals for RawConnectionDriver.

@mattklein123 @htuch @alyssawilk WDYT?

@mattklein123
Copy link
Member

@jmarantz at a high level, we don't create files in any high performance path. Is it worth the code churn here? (I haven't actually reviewed yet but trying to understand if the overall change is worth it.)

@htuch
Copy link
Member

htuch commented Nov 14, 2018

On the envoy-filter-example front, I have an idea how to make this dance less insane:

  1. We move envoy-filter-example into the main Envoy repo, using a local repository in the WORKSPACE to point the example at Envoy source.
  2. We export to envoy-filter-example as a read-only mirror (like data-plane-api), and swizzle the WORKSPACE to one that uses a remote repository.

This preserves envoy-filter-example as a standalone example of integrating Envoy, while avoiding the multi-phase commit dance (and breakages) we hit regularly these days. WDYT?

@mattklein123
Copy link
Member

This preserves envoy-filter-example as a standalone example of integrating Envoy, while avoiding the multi-phase commit dance (and breakages) we hit regularly these days. WDYT?

This sounds awesome. We could also then test it as part of the main CI.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
…tead make an IsolatedStatsStore.

This should avoid the problems copmiling echo2_integration_test.cc in a separate repo.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
@alyssawilk
Copy link
Contributor

@jmarantz at a high level, we don't create files in any high performance path. Is it worth the code churn here? (I haven't actually reviewed yet but trying to understand if the overall change is worth it.)

Agreed - while I'm all for lockless code where possible, I also don't think of file operations as generally being performance critical - once you're looking at disk you're already on a slow path. Where is this problematic?

@jmarantz
Copy link
Contributor Author

It's possible this might not be performance critical in real examples, but I also have refactored away for the need to change the API for filter-examples, so I'm hopeful that asan/tsan CI will just pass now.

It might still not be worth the churn, but there's less churn now :)

The reason this crossed my radar is that envoy-perf/siege/siege.py (which I wrote) uses a static file for serving origin content for the load test. IMO it's a justifiable refactor to give the file-system some context.

@mattklein123
Copy link
Member

OK can you merge master and we can take a look and discuss?

Signed-off-by: Joshua Marantz <jmarantz@google.com>
@htuch
Copy link
Member

htuch commented Nov 15, 2018

This preserves envoy-filter-example as a standalone example of integrating Envoy, while avoiding the multi-phase commit dance (and breakages) we hit regularly these days. WDYT?

This sounds awesome. We could also then test it as part of the main CI.

I've created #5054 to track. I might have cycles to work on this coming up, so tentatively assigned to me.

@jmarantz
Copy link
Contributor Author

jmarantz commented Nov 15, 2018

Very cool, @htuch.

FWIW this PR is not blocked on that now, but on the merging of master, which just added many instantiations of Api::ApiImpl throughout tests, and this PR makes it impossible to default-construct an Api::ApiImpl. It's of course still possible (but more cumbersome) to instantiate Api::ApiImpl in lots of places in tests.

I proposed (off-list) that createThread() be delegated to a ThreadSystem class, owned by ApiImpl but separately injectable. Most of the Api::ApiImpl instantiations that were just added to tests can then just instantiate a ThreadSystem.

I think this scales better as Api grows to encompass more functionality, some of which may require context to be passed into the constructor. I discussed this f2f with @eziskind and will follow up further.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@jmarantz
Copy link
Contributor Author

ptal; this is now merged and ready for review.

htuch pushed a commit that referenced this pull request Nov 21, 2018
For the record, I am against singletons in general, and believe it's more maintainable to pass context objects through the call/instantiation stack, as is done in Envoy production code. However the test system employs a deep system of mocks that are constructed without context. As a result, any new context that may be needed in the future (e.g. SymbolTable in #4980, ThreadSystem in #5055 and #5072 and FileSystem in #5031) need a mechanism to plumb data into the system as instantiated during tests. I believe Api::OsSysCalls() is another example that might benefit from this.

This class provides a mechanism to have a bounded-scope singleton, such that anywhere an instance of a type T is desired, the same instance will be available. Once all references to a Global go out of scope, the shared instance is destroyed and the pointer to it nulled.

Thus, this singleton pattern has the property that between tests, the state will be completely reset, as long as there are no memory leaks.

The new class, Test::Global, creates a potential conflict with tests that had declared using testing::Test;, so this PR also cleans those up and adds a format check to avoid having that pattern re-occur.

Risk Level: the main risk here is that this class will be abused and used in lieu of proper object passing when that's most appropriate. However, the new library is declared as a bazel test library and is in the test/... tree, so hopefully -- with proper code reviews, the usage will be limited.
Testing: //test/...

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@mattklein123
Copy link
Member

/retest

@repokitteh-read-only
Copy link

🔨 rebuilding ci/circleci: mac (failed build)

🐱

Caused by: a #5031 (comment) was created by @mattklein123.

see: more, trace.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

LGTM, small comments. Thank you!

/wait

ASSERT(scopes_.empty());
}

void ThreadLocalStoreImpl::setStatsMatcher(StatsMatcherPtr&& stats_matcher) {
Copy link
Member

Choose a reason for hiding this comment

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

This seems unrelated to filesystems. Thoughts on moving this part of the change to a different PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I needed to tackle this was that pre-declaring the stats for the filesystem at API creation time made them all leak through the late application of the StatsMatcher and broke the StatsMatcher integration test, which already had one hardcoded exception in it.

I felt it better to clean up the matcher than had a lot more exceptions to the integration-test.

However what I can do is put that into its own PR which we can review first.

Copy link
Member

Choose a reason for hiding this comment

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

Great, SGTM. Thanks for breaking things apart.

Copy link
Contributor Author

@jmarantz jmarantz Nov 24, 2018

Choose a reason for hiding this comment

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

Pulled into #5105 which can be reviewed without the file-system change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#5105 is merged now and so is no longer part of this PR.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@mattklein123 mattklein123 merged commit a59709c into envoyproxy:master Nov 26, 2018
@jmarantz jmarantz deleted the filesystem-stats branch November 26, 2018 21:38
fredlas pushed a commit to fredlas/envoy that referenced this pull request Mar 5, 2019
For the record, I am against singletons in general, and believe it's more maintainable to pass context objects through the call/instantiation stack, as is done in Envoy production code. However the test system employs a deep system of mocks that are constructed without context. As a result, any new context that may be needed in the future (e.g. SymbolTable in envoyproxy#4980, ThreadSystem in envoyproxy#5055 and envoyproxy#5072 and FileSystem in envoyproxy#5031) need a mechanism to plumb data into the system as instantiated during tests. I believe Api::OsSysCalls() is another example that might benefit from this.

This class provides a mechanism to have a bounded-scope singleton, such that anywhere an instance of a type T is desired, the same instance will be available. Once all references to a Global go out of scope, the shared instance is destroyed and the pointer to it nulled.

Thus, this singleton pattern has the property that between tests, the state will be completely reset, as long as there are no memory leaks.

The new class, Test::Global, creates a potential conflict with tests that had declared using testing::Test;, so this PR also cleans those up and adds a format check to avoid having that pattern re-occur.

Risk Level: the main risk here is that this class will be abused and used in lieu of proper object passing when that's most appropriate. However, the new library is declared as a bazel test library and is in the test/... tree, so hopefully -- with proper code reviews, the usage will be limited.
Testing: //test/...

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this pull request Mar 5, 2019
…ld the stats counters. (envoyproxy#5031)

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
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