-
-
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. | |
| 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() |
that amazing super script
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!
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
This made my day, Thanks Kent!