0

Here is the case.
I start a telegram bot(using pyrogram framework) inside django and everytime that I modify a file and save it or django just restarts by any reason, I have to shut pyrogram down right before django starts again.
If I do not shut down pyrogram right before server restart process, it gets stuck after printing a sentence like:

<modified_file_address> changed, reloading.

And after this line, nothing happens and django will not start itself again and I just found source of the problem.
Pyrogram(v0.18.0 - synchronous version) is causing it because of multithreading lock keys.(a little bit complicated to describe and not related to the question)
If I can shutdown pyrogram bot right before running the django server again(literally right before or after printing <modified_file_address> changed, reloading. message), I can fix it.
After searching inside the django source code, this is the function that actually prints that message.

# inside django.utils

def trigger_reload(filename):
    logger.info('%s changed, reloading.', filename)
    sys.exit(3)

And now this is my question:

Is There Any Way To Overwrite trigger_reload Function Or Customize It Somehow?

And if no:

Is There Any Way To Run A Function Right Before trigger_reload Function?

And if no again:

Is It Possible To Use Another Django Reloader And Customize It To Shutdown The Bot?

And if no again, what should I do?
Any suggestions?

Mahmood
  • 403
  • 2
  • 10
  • 1
    related: https://stackoverflow.com/questions/59516057/django-manage-py-runserver-graceful-reloading – He3lixxx May 18 '21 at 21:23

1 Answers1

1

trigger_reload will be called by notify_file_changed. Before it calls that, it will trigger the file_changed signal. So, you could register a handler for it.

If you make your handler return a truthy value, it will stop the autoreload. Otherwise, if it doesn't return of returns a falsy value, the reload will continue. You could use this to either implement your own restart logic, or jump implement some teardown logic and then keep the original django autoreload:

from django.dispatch import receiver
from django.utils.autoreload import file_changed

@receiver(file_changed)
def on_file_changed(sender, **kwargs):
    print("Custom file changed...")
    return True  # returning a truthy value prevents the reload.

None of this is documented, I think, so it might break with future releases. I simply looked at the current django code.

He3lixxx
  • 3,263
  • 1
  • 12
  • 31
  • Thank you seriously, you helped me a lot. And anyway, if anyone else is reading this comment, I used `autoreload_started` signal too. You can import both of those signals like `from django.utils.autoreload import file_changed, autoreload_started` and my friend up here said how to make use out of them. And now I start my bot when `autoreload_started` signal meets and shut it down when `file_changed` signal meets. – Mahmood May 19 '21 at 05:22