Skip to content
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

Allow graceful interruption of worker sleep #928

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

romuloceccon
Copy link

When daemonized through Delayed::Command Delayed::Worker will ignore signals every time it sleeps after detecting an empty queue. That's specially problematic when using a long sleep_delay (30+ seconds) with a predominantly idle queue, because the Daemons gem will forcefully kill the process if it's not responsive.

Another way the issue manifests is when executing something like the following:

Delayed::Worker.sleep_delay = 30.seconds
Delayed::Command.new(['run']).daemonize

Trying to stop the command with Ctrl-C outputs a message Exiting..., but nothing else happens, apparently. The command does stop, however, after the full sleep_delay interval elapses.

The root cause is a sleep call in Delayed::Worker, which cannot be interrupted unless a signal is raised. Since raising signals is often undesirable because it might also interrupt unfinished jobs we need to address only the case when Delayed::Worker is sleeping.

This patch offers a solution, which consists in substituting the sleep call with a wait on an event. Setting the event from the trap enables the worker to exit immediately. Otherwise, if the timeout given to the wait call elapses, everything behaves as if sleep was called.

This resolves the issue #593 and may also be related to #459 and #916.

Previously, unless `Worker.raise_signal_exceptions` was set, the worker
process ignored INT and TERM signals while sleeping after detection of
an empty queue. That behavior was specially noticeable when
`sleep_delay` was much greater than the default of 5 seconds: a
daemonized job, for example, would end up being killed because of not
responding in a reasonable time.

Now, when the worker needs to sleep, it does so waiting on an event with
a timeout. Stopping the job from a signal sets the event and aborts the
wait immediately.
@coveralls
Copy link

coveralls commented Jul 4, 2016

Coverage Status

Coverage increased (+0.5%) to 91.587% when pulling a63f213 on romuloceccon:graceful_sleep_interruption into e3772d4 on collectiveidea:master.

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.

None yet

2 participants