Created
March 10, 2016 10:45
-
-
Save chenjianjx/53d8c2317f6023dc2fa0 to your computer and use it in GitHub Desktop.
A python script which starts celery worker and auto reload it when any code change happens.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
A python script which starts celery worker and auto reload it when any code change happens. | |
I did this because Celery worker's "--autoreload" option seems not working for a lot of people. | |
''' | |
import time | |
from watchdog.observers import Observer ##pip install watchdog | |
from watchdog.events import PatternMatchingEventHandler | |
import psutil ##pip install psutil | |
import os | |
import subprocess | |
code_dir_to_monitor = "/path/to/your/code/dir" | |
celery_working_dir = code_dir_to_monitor #happen to be the same. It may be different on your machine | |
celery_cmdline = 'celery worker -A some_project -l INFO'.split(" ") | |
class MyHandler(PatternMatchingEventHandler): | |
def on_any_event(self, event): | |
print("detected change. event = {}".format(event)) | |
for proc in psutil.process_iter(): | |
proc_cmdline = self._get_proc_cmdline(proc) | |
if not proc_cmdline or len(proc_cmdline) < len(celery_cmdline): | |
continue | |
is_celery_worker = 'python' in proc_cmdline[0].lower() \ | |
and celery_cmdline[0] == proc_cmdline[1] \ | |
and celery_cmdline[1] == proc_cmdline[2] | |
if not is_celery_worker: | |
continue | |
proc.kill() | |
print("Just killed {} on working dir {}".format(proc_cmdline, proc.cwd())) | |
run_worker() | |
def _get_proc_cmdline(self, proc): | |
try: | |
return proc.cmdline() | |
except Exception as e: | |
return [] | |
def run_worker(): | |
print("Ready to call {} ".format(celery_cmdline)) | |
os.chdir(celery_working_dir) | |
subprocess.Popen(celery_cmdline) | |
print("Done callling {} ".format(celery_cmdline)) | |
if __name__ == "__main__": | |
run_worker() | |
event_handler = MyHandler(patterns = ["*.py"]) | |
observer = Observer() | |
observer.schedule(event_handler, code_dir_to_monitor, recursive=True) | |
observer.start() | |
print("file change observer started") | |
try: | |
while True: | |
time.sleep(1) | |
except KeyboardInterrupt: | |
observer.stop() | |
observer.join() |
Bravo !!! Thanks for sharing
You are a genius! Thank you so so much! I was about to go crazy manually restarting my celery workers on windows everytime I changed my tasks.
I had to change the on_any_event function because I'm using winpython (need to open a seperate shell):
Had to start the new worker before killing the old process
def on_any_event(self, event):
print("detected change. event = {}".format(event))
for proc in psutil.process_iter():
proc_cmdline = self._get_proc_cmdline(proc)
if not proc_cmdline or len(proc_cmdline) < len(celery_cmdline):
continue
is_celery_worker = 'python' in proc_cmdline[0].lower() \
and celery_cmdline[0] in proc_cmdline[1] \
and celery_cmdline[1] == proc_cmdline[2]
if not is_celery_worker:
continue
try:
run_worker()
print("Just killed {} on working dir {}".format(proc_cmdline, proc.cwd()))
proc.kill()
break
except Exception as e:
print(str(e))
Thanks for the code, I'm also using python on windows, and when running your suggestion with proc.kill()
I'm getting psutil.NoSuchProcess process no longer exists (pid=11800)
, any ideas?
did you experience memory leak using this script ? it eats up 40% of my memory
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Even you created this script two years ago, it still works like a charm! Thanks!
I adjusted line 28 to 'in' instead of '==' because i run it in a docker.
Cheers!