-
Notifications
You must be signed in to change notification settings - Fork 13
profile-id improvements #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
4fb0cf6 to
0392954
Compare
|
once approved -- i would like to try this branch first in production before cutting a new release |
lib/app_profiler/base_profile.rb
Outdated
| # a vernier "result" object for vernier | ||
| def initialize(data, id: nil, context: nil) | ||
| @id = id.presence || ProfileId.current | ||
| ProfileId.set(id) if id.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were not doing this before. If someone provides an Id we should set ProfileId too so that the values are consistent.
manuelfelipe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now persist profile_id in metadata, so that the clients do not have to do this.
nice. Thanks for that!
Now that looked at the corresponding prod change, maybe we should also add the |
96e054d to
785570c
Compare
785570c to
c8595fb
Compare
lib/app_profiler/base_profile.rb
Outdated
| def initialize(data, id: nil, context: nil) | ||
| @id = id.presence || ProfileId.current | ||
| ProfileId.set(id) if id.present? | ||
| @id = ProfileId.current |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO You don't need to track this as an ivar anymore. Any call should use the current value. You can only have 1 profile per request, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a good point 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed this to:
def id
metadata[PROFILE_ID_METADATA_KEY]
end
|
|
||
| module AppProfiler | ||
| PROFILE_ID_METADATA_KEY = :profile_id | ||
| PROFILE_BACKEND_METADATA_KEY = :profiler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would keep these in BaseProfile. Putting them in two places doesn't really make sense if they're solely used there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clients can use these ids when dealing with profile metadata. I think accessing it as AppProfiler:: PROFILE_ID_METADATA_KEY is better than nesting it under BaseProfile. I have removed it from BaseProfile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, as long as it isn't repeated I'm happy. 👍
lib/app_profiler/base_profile.rb
Outdated
| private_constant :INTERNAL_METADATA_KEYS | ||
| class UnsafeFilename < StandardError; end | ||
| PROFILE_ID_METADATA_KEY = :profile_id | ||
| PROFILE_BACKEND_METADATA_KEY = :profiler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'd consider adding these to private_const above, but not strictly necessary if you need them in tests. You could just use the plain value there instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
|
@gmcgibbon how bad would it be if I change this to app_profiler/lib/app_profiler/base_profile.rb Line 100 in dadf2e5
profile object, instead of metadata?
This is quite recent, like a week or so ago -- so not sure if there are usages out in the wild 😬 Will allow us to just use the profile object and its methods (id is now deeply integrated). I kind of dread i did not do this to start with. |
gmcgibbon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after these changes
lib/app_profiler/vernier_profile.rb
Outdated
|
|
||
| class << self | ||
| def backend_name | ||
| NAME # cannot reference Backend::VernierBackend because of different ruby versions we have to support |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| NAME # cannot reference Backend::VernierBackend because of different ruby versions we have to support | |
| BACKEND_NAME |
Are you able to make Backend::VernierBackend.name and other classes reference this constant so we're not repeating ourselves? We need to eventually add loading tests to make sure we don't regress #155.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done - think I did all of them
> Rg "AppProfiler::Backend::VernierBackend.name" .
# returns nothing
> Rg "AppProfiler::VernierProfile::BACKEND_NAME" .
./test/app_profiler/run_test.rb
35: AppProfiler.run(backend: AppProfiler::VernierProfile::BACKEND_NAME) do
36: assert_equal(AppProfiler::VernierProfile::BACKEND_NAME, AppProfiler.backend)
./lib/app_profiler.rb
167: backend_name&.to_sym == AppProfiler::VernierProfile::BACKEND_NAME
181: RUBY_VERSION >= "3.2.1" && defined?(AppProfiler::VernierProfile::BACKEND_NAME)
./lib/app_profiler/request_parameters.rb
36: if AppProfiler.vernier_supported? && backend == AppProfiler::VernierProfile::BACKEND_NAME &&
./test/app_profiler/backend_test.rb
12: assert_raises(BackendError) { AppProfiler.backend = AppProfiler::VernierProfile::BACKEND_NAME }
24: assert(AppProfiler.backend = AppProfiler::VernierProfile::BACKEND_NAME)
25: assert_equal(AppProfiler.backend, AppProfiler::VernierProfile::BACKEND_NAME)
52: AppProfiler.backend_for(AppProfiler::VernierProfile::BACKEND_NAME),
test/app_profiler/middleware_test.rb
Outdated
| middleware.call(mock_request_env(path: "/?profile=cpu")) | ||
| end | ||
| end | ||
| assert_nil(Thread.current[ProfileId::PROFILE_ID_KEY]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| assert_nil(Thread.current[ProfileId::PROFILE_ID_KEY]) | |
| assert_nil(ProfileId.current) |
If you want to test threads, you can do so in a ProfileId test. Now that we aren't using current attributes we should test this more thoroughly anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will think of adding more meaningful threads in ProfileId tests. But. given what we found for current attributes regarding order of middlewars, I specifically wanted to test this after middleware has run and finished. I ack this feels a bit out of of place - but is kind of of imp. Alternatively, I can expose a method nil? which is used only for tests and is without any side-effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added some basics tests for threads 1694438#diff-ad5a82381a58be0174af1d3fd8d65974e9aa806549a942ce058b482130edc42fR14
|
|
||
| module AppProfiler | ||
| PROFILE_ID_METADATA_KEY = :profile_id | ||
| PROFILE_BACKEND_METADATA_KEY = :profiler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, as long as it isn't repeated I'm happy. 👍
|
@bmansoob You can make that change, but because it is a released feature you need to think about deprecation cycling the old behaviour. I would wrap a proc on assignment that checks if the type of the input. What you could do is:
|
thanks -- something to ponder and do in a separate PR 😅 |
|
I will squash the commits in a bit and test this branch in production before cutting a new release. |
1694438 to
2a49a66
Compare
|
squashed |
|
direction change - going to merge and release the gem. |
CurrentAttributeswith local thread storage which gets reset by the middleware at the end. The reason for this is if the profiling middleware runs before this, then the value would be inconsistent if it is read again on the way out (sending response back). I have tried to maintain the same API interface so that it does not break existing clients