-
Notifications
You must be signed in to change notification settings - Fork 1
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
fix: register reloadable config variables #108
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #108 +/- ##
==========================================
+ Coverage 78.70% 79.37% +0.66%
==========================================
Files 68 68
Lines 4866 5087 +221
==========================================
+ Hits 3830 4038 +208
- Misses 830 849 +19
+ Partials 206 200 -6
☔ View full report in Codecov by Sentry. |
LGTM |
One major issue we are having now with the RegisterXxx API is that the config package keeps pointers to fields of other structs, e.g. router, batchrouter, jobsdb handes etc. so these structs are never garbage collected even though they might no longer be needed by the system (see MT rudder server stop/start sequences). So we end up with a slow-burning memory leak. |
@atzoum I wasn't aware of the memory leaks, I'll have a look 👍 |
f829851
to
b2eb639
Compare
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.
thank you @fracasula for taking the extra time to try and address important issues with our reloadable configs!
config/hotreloadable.go
Outdated
// RegisterAtomicIntVar registers a hot-reloadable int config variable | ||
// Copy of RegisterIntConfigVariable, but with a way to avoid data races for hot reloadable config variables | ||
func (c *Config) RegisterAtomicIntVar(defaultValue, valueScale int, keys ...string) *Atomic[int] { | ||
ptr := getOrCreatePointer(c.atomicVars, c.atomicVarsMisuses, &c.atomicVarsLock, defaultValue, keys...) |
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.
Whenever we are reusing an existing pointer we shouldn't register it again.
If getOrCreatePointer
returned a second value indicating whether this is a new or existing pointer, we could use this information for avoiding registering it twice.
One thing we should definitely fix though is whenever we are calling appendVarToConfigMaps
, we should pass as a key the full concatenated key instead of the first key from the slice.
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.
One thing we should definitely fix though is whenever we are calling
appendVarToConfigMaps
, we should pass as a key the full concatenated key instead of the first key from the slice.
Nice, good catch 👍
Whenever we are reusing an existing pointer we shouldn't register it again. If
getOrCreatePointer
returned a second value indicating whether this is a new or existing pointer, we could use this information for avoiding registering it twice.
We could allow this though, it is now safe to do so and you'll get the same variable. I'm keen to let people do it at this point. If someone misuses the default values will get a panic as well. Perhaps we should settle on the discussion about the order of the keys first, I might be missing some use case.
config/config.go
Outdated
atomicVars map[string]any | ||
atomicVarsMisuses map[string]string | ||
atomicVarsLock sync.RWMutex // used to protect both atomicVars maps |
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.
Minor: since all these fields are part of the hot-reloadable feature we could use hotReloadableConfigLock
instead of atomicVarsLock
, is there an actual need for a second lock?
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.
They are used at different times and to protect different data so I'm keen to keep both actually to minimize lock contention. It seems like a small price to pay.
bb0e5a4
to
6e01bd3
Compare
Description
Now that we're running warehouse tests with the
-race
flags (used in order to prevent races to go to production), we're seeing random failures in some tests (e.g. snowflake integrations) with hot-reloadable configs.This PR tries to address the issue in a backwards compatible manner and by providing a succint alternative to use the new API without having to burden ourselves with locking and unlocking mutexes each time we have to deal with such variables.
Context
Linear Ticket
< Linear Link >
Security