Skip to content

Do not set SIGTERM handler in Task.__call__() #5775

@rneilson

Description

@rneilson

PR #5423 (to address issue #2700) made a change which installs a SIGTERM handler within Task.__call__(), which effectively ignores SIGTERM. This is...er...wrong, and leads to the following problems:

  • Tasks cannot be called inline within a thread (eg common configurations of uwsgi, or even Django's runserver)
  • The warm/cold shutdown distinction is erased
  • The REMAP_SIGTERM configuration value is ignored (used in eg Heroku deployments)
  • Signal handling by non-worker calling processes is forcibly overridden
  • Conflicts with Celery's own worker signal handling (see worker.py and platforms.py)

The PR in question was reverted in #5577, then un-reverted in #5586.

We've had to add a custom task class and override __call__() for production use to avoid this issue. Please re-revert #5423; if #2700 is still an issue inherent to Celery (as opposed to simply warm/cold shutdown differences), then a different fix should be considered.

Edit: after some deeper looks at the code, it seems as though this only applies for inline tasks under the base Task class, as __call__() is optimized away (see trace.py) for async/dispatched tasks if it hasn't been overridden. AFAICT it would still be a problem if using a custom task class which overrides __call__() and calls super(), however.

Checklist

  • I have read the relevant section in the
    contribution guide
    on reporting bugs.
  • I have checked the issues list
    for similar or identical bug reports.
  • I have checked the pull requests list
    for existing proposed fixes.
  • I have checked the commit log
    to find out if the bug was already fixed in the master branch.
  • I have included all related issues and possible duplicate issues
    in this issue (If there are none, check this box anyway).

Mandatory Debugging Information

  • I have included the output of celery -A proj report in the issue.
    (if you are not able to do this, then at least specify the Celery
    version affected).
  • I have verified that the issue exists against the master branch of Celery.
  • I have included the contents of pip freeze in the issue.
  • I have included all the versions of all the external dependencies required
    to reproduce this bug.

Related Issues and Possible Duplicates

Related Issues

Possible Duplicates

  • None

Environment & Settings

Celery version:

celery report Output:

software -> celery:4.4.0rc3 (cliffs) kombu:4.6.4 py:3.7.4
            billiard:3.6.1.0 redis:3.3.7
platform -> system:Linux arch:64bit
            kernel version:4.9.184-linuxkit imp:CPython
loader   -> celery.loaders.app.AppLoader
settings -> transport:redis results:redis://mps-redis:6379/0

Steps to Reproduce

Required Dependencies

  • Minimal Python Version: N/A or Unknown
  • Minimal Celery Version: 4.4.0rc2
  • Minimal Kombu Version: N/A or Unknown
  • Minimal Broker Version: N/A or Unknown
  • Minimal Result Backend Version: N/A or Unknown
  • Minimal OS and/or Kernel Version: N/A or Unknown
  • Minimal Broker Client Version: N/A or Unknown
  • Minimal Result Backend Client Version: N/A or Unknown

Minimally Reproducible Test Case

See https://github.com/celery/celery/blob/master/celery/app/task.py#L396

Expected Behavior

Should be able to call a task inline in a thread.

Actual Behavior

When calling task inline under Django runserver (which uses threads):

Traceback (most recent call last):
  File "/app/pipelines/serializers.py", line 184, in create
    remote_worker=validated_data['with_remote'],
  File "/usr/local/lib/python3.7/site-packages/celery/local.py", line 191, in __call__
    return self._get_current_object()(*a, **kw)
  File "/usr/local/lib/python3.7/site-packages/celery/app/task.py", line 396, in __call__
    signal.signal(signal.SIGTERM, handle_sigterm)
  File "/usr/local/lib/python3.7/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions