-
Notifications
You must be signed in to change notification settings - Fork 375
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
[PROF-9136] Fix rare remote configuration worker thread leak #3519
Changes from 1 commit
7df5858
760e084
22f3330
e20cbaf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,20 +10,25 @@ def initialize(interval:, &block) | |
@thr = nil | ||
|
||
@starting = false | ||
@stopping = false | ||
@started = false | ||
@stop_requested = false | ||
|
||
@interval = interval | ||
raise ArgumentError, 'can not initialize a worker without a block' unless block | ||
|
||
@block = block | ||
end | ||
|
||
def start | ||
def start(allow_restart: false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a situation where we want to allow restart? My memory is a bit fuzzy but it seemed to me that once a remote worker has started in practice its only subsequent states are "stopping" and "stopped", but maybe I missed something? (IOW is state 5. disallowed and maybe should be guarded against?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed in 760e084 |
||
Datadog.logger.debug { 'remote worker starting' } | ||
|
||
acquire_lock | ||
|
||
if @stop_requested && !allow_restart | ||
Datadog.logger.debug('remote worker: refusing to restart after previous stop') | ||
return | ||
end | ||
|
||
return if @starting || @started | ||
|
||
@starting = true | ||
|
@@ -46,8 +51,6 @@ def stop | |
|
||
acquire_lock | ||
|
||
@stopping = true | ||
|
||
thread = @thr | ||
|
||
if thread | ||
|
@@ -56,8 +59,8 @@ def stop | |
end | ||
|
||
@started = false | ||
@stopping = false | ||
@thr = nil | ||
@stop_requested = true | ||
|
||
Datadog.logger.debug { 'remote worker stopped' } | ||
ensure | ||
|
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.
Not fond of what the naming implies here ^^', I feel it introduces incidental complexity.
Here's my train of thought.
This sequence diagram shows how I view the state machine†:
In that context,
stop_requested
captures a transition (IOW#stop
has been called) instead of representing a state. In effect this leads to a representational issue:@stop_requested
will be forevertrue
even when a restartable worker has been restarted and no#stop
has been issued to that second#start
state.AIUI what
stop_requested
intends to introduce is:@allow_restart
@stopping
.As a consequence I feel introducing a
stopped
state would better represent all possible states:It then follows that:
@allow_restart
is only effective whenstopped
(and not effective when¬stopped
)stop_requested
is equivalent tostopping OR stopped
started
; in that cas I feel a stop count (or maybe better, a start count) could be usefulstop_requested
on a restartable worker is resolved and fully captured bystopping
I also feel it makes it easier to implement helper methods from these fundamental state primitives (e.g synthesising
#stop_requested
if needed)†
success
is actually a diamond with anerror
branch, elided so as not to overload the sequence diagram, and also because it happens via exceptional code flow.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
@stop_requested
to@stopped
in 22f3330