Skip to content

Instantly share code, notes, and snippets.

@dangayle
Forked from jonhuber/celery_janitor.py
Created December 10, 2015 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dangayle/7e0ddf5c2039c37ee624 to your computer and use it in GitHub Desktop.
Save dangayle/7e0ddf5c2039c37ee624 to your computer and use it in GitHub Desktop.
This is a script to clean up deadlocked Celery workers. I typically run it on servers every 15 minutes via cron.
from celery.app.control import Control
import datetime
import psutil
import socket
def main():
control = Control()
inspect = control.inspect()
hostname = socket.gethostname()
print('Starting celery process cleanup ({0})'.format(datetime.datetime.now()))
# Get the all of parent celery processes
processes = psutil.get_process_list()
celeryd_processes = [
x for x in processes
if x.name == 'celeryd'
and x.parent
and x.parent.name != 'celeryd'
]
# Determine worker name on each process
celeryd_process_lookup = {}
for process in celeryd_processes:
for arg in process.cmdline:
if hostname in arg:
worker_name = arg
celeryd_process_lookup[worker_name] = process
# Find workers that are still listening -- not dead
good_workers = [x for x in inspect.ping().keys() if hostname in x]
# Kill bad worker processes
for worker in good_workers:
celeryd_process_lookup[worker] = None
for worker_name, process in celeryd_process_lookup.items():
if process:
print('Killing {worker_name} with PID of {pid}'.format(
worker_name=worker_name,
pid=process.pid
))
process.kill()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment