-
Notifications
You must be signed in to change notification settings - Fork 51
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
Handle the SIGINT and SIGTERM signals to support stopping a test cleanly #84
Conversation
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 certainly a good start. I have a request to use some form of atomic semantic for the flag variable and I would also like to see a follow-up issue describing using a cancellable context.Context
.
internal/cli/run/run.go
Outdated
go func() { | ||
<-s | ||
log.Debugf("caught a signal, shutting down cleanly") | ||
ctx.IsTerminated = true |
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.
Please, use atomic
to make sure we're accessing the variable with atomic semantics. I am thinking at something like atomic.AddInt64(&ctx.IsTerminated)
to stop and atomic.LoadInt64(&ctx.IsTerminated)
to fetch it.
Unfortunately there is no atomic boolean. If you wish to retain a boolan type, otherwise use a sync.Mutex
but I have a mild preference for atomic semantics because it's more robust than explicitly using mutexes.
internal/cli/run/run.go
Outdated
@@ -13,6 +16,20 @@ import ( | |||
"github.com/ooni/probe-cli/nettests" | |||
) | |||
|
|||
// listenForSignals will listen for SIGINT and SIGTERM. When it receives those | |||
// signals it will set isTerminated to true, which will cleanly shutdown the | |||
// test logic |
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.
Please, document that the proper way to attain this objective would instead be to use a context.Context
and cancel it when a signal is delivered, but this kind of refactoring is too complex for now. It would perhaps be top to have an issue that suggests to use a cancellable context rather than just adding a TODO comment to the code.
I agree with you that using a Regarding the atomic semantics for the flag, I am not sure I properly understand what race condition or inconsistency you are concerned about. Throughout the rest of the code this variable is only ever read, so I am not really sure what we are gaining by using an Since the setup is that of a single writer, I don't see it possible for a race condition and I think using the atomic construct is unnecessary. |
Following a private chat with @bassosimone I was enlightened by the magic that happens in the golang memory model, see: https://golang.org/ref/mem. Some key takeways from that text include:
and
Moreover a minimal version of our code like this:
results in a race being detected by the golang race detector. |
I pushed changes that implement the recommended atomic patterns. |
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 fixes: #76