Backend server hot reload in development mode
Closed this issue · 3 comments
Hello, when running multivisor web server with command python -m multivisor.server.web -c multivisor.conf
and with flask env variable FLASK_ENV=development
I don't get a server reload after changes in .py files. Which is painful of course, because I keep on forgetting about reloading it manually. I can see that project is using WSGI server from gevent.pywsgi module
:
http_server = WSGIServer(bind, application=app)
logging.info('Start accepting requests')
try:
http_server.serve_forever()
except KeyboardInterrupt:
log.info('Ctrl-C pressed. Bailing out')
I tried to replace this with flask run function:
if app.debug:
host, port = bind.split(':')
app.run(host=host, port=port)
else:
http_server = WSGIServer(bind, application=app)
...
But unfortunately I get the following exception from time to time:
File "/home/stevens/PycharmProjects/multivisor/multivisor/multivisor.py", line 430, in _do_processes
joinall(tasks)
File "src/gevent/greenlet.py", line 899, in gevent._greenlet.joinall
File "src/gevent/greenlet.py", line 909, in gevent._greenlet.joinall
File "src/gevent/_hub_primitives.py", line 217, in gevent.__hub_primitives.wait_on_objects
File "src/gevent/_hub_primitives.py", line 254, in gevent.__hub_primitives.wait_on_objects
File "src/gevent/_hub_primitives.py", line 152, in gevent.__hub_primitives._WaitIterator.__next__
File "src/gevent/_hub_primitives.py", line 143, in gevent.__hub_primitives._WaitIterator.__next__
File "src/gevent/_waiter.py", line 192, in gevent.__waiter.MultipleWaiter.get
File "src/gevent/_waiter.py", line 151, in gevent.__waiter.Waiter.get
File "src/gevent/_greenlet_primitives.py", line 60, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/_greenlet_primitives.py", line 60, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/_greenlet_primitives.py", line 64, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch
LoopExit: This operation would block forever
Hub: <Hub '' at 0x7fec429e5680 epoll pending=0 ref=0 fileno=34 thread_ident=0x7fec4170c700>
Handles:
[]
Traceback (most recent call last):
File "src/gevent/queue.py", line 667, in gevent._queue.Channel._unlock
File "src/gevent/_waiter.py", line 116, in gevent.__waiter.Waiter.switch
AssertionError: Can only use Waiter.switch method from the Hub greenlet
Do you think there is any way we could solve this?
Also, I noticed that I cannot run the server the way it is described in README.md:
python -m multivisor.server -c multivisor.conf
returns
No module named multivisor.server.__main__; 'multivisor.server' is a package and cannot be directly executed
So I use: python -m multivisor.server.web -c multivisor.conf
I understand your frustration. It is completely reasonable.
The thing is you definitively need to run a gevent WSGI. Main reason is the underlying ZeroRPC library is based on gevent. When you implement a coroutine based solution you need to go coroutine 100%.
Searching a bit on the web the closest solution I could find was this gist.
I didn't give it a try so I don't know if it works.
Let me know if you have time to try it out. If not I might have a look.
Thanks a lot for your explaination @tiagocoutinho. I will have a look and let you know.
Issue fixed in develop branch
Will become visible in next release