I am using Python 3.10.11, Flask 3.0.0 and Werkzeug 3.0.1. I've worked on a project for couple of months, took a break and now, couple of months later for some reason the hot reload doesn't work. Instead, it throws this error. Moreover, Sometimes the app doesn't update even when I restart it (close and start new terminal). I tried solving this issue as an environmental issue and as a version mismatch issue but both solutions ended up not working. I don't have any sockets in my app as well.
Exception in thread Thread-2 (serve_forever):
Traceback (most recent call last):
File "C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016, in _bootstrap_inner
self.run()
File "C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\site-packages\werkzeug\serving.py", line 806, in serve_forever
super().serve_forever(poll_interval=poll_interval)
File "C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\socketserver.py", line 232, in serve_forever
ready = selector.select(poll_interval)
File "C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\selectors.py", line 324, in select
r, w, _ = self._select(self._readers, self._writers, [], timeout)
File "C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\selectors.py", line 315, in _select
r, w, x = select.select(r, w, w, timeout)
OSError: [WinError 10038] An operation was attempted on something that is not a socket
I am using pipenv, tried running the app in multiple ways.
flask --debug run
py ./app.py
pipenv run py ./app.py
I just can't understand why it stopped working. I checked for version mismatch and tried changing multiple python versions, and multiple Flask & Werkzeug versions, unfortunately with no luck.
I tried reseting netsh: netsh winsock reset as presented here but with no luck as well.
I tried deleting the environment and creating a new one. I ran this app globally and locally (in env) but got the same issue. Sometimes running in environment it catches only the first reload and then stops working (without any reload options)
I am clueless. What can cause this? My only guess is maybe when it tries to reload the app, it crashes somewhere that I can't "Ctrl + C" out of and this causes a loop which corrupts the whole listening port. Changing ports doesn't work either.
@JohnGordon and @MarkTolonen were right. I was trying to fix the problem for hours without even knowing what line caused it. I stripped out all the logic and found out that the line
db = MyDBClass()in my main flask app was causing the error.What caused the error
My db class had a function that ran in a separate, detached thread which handled its request queue. As lots of requests were coming in simultaneously, This thread was a must for my database in order to not mix the results given to the requests. Hot reloading the flask app created multiple database instances which created multiple threads connected to the same database. Two threads can't access the same database and therefore we got this error.
Fix: Flask's global namespace
gFlask gives us a global namespace to use within an application context. According to Flask's documentation:
So, for each request, the database class will be initiated again. This means a thread can now properly be terminated (of course it's termination must be implemented in
YourDBClass.__del__()) before a new one is created. Now multiple threads will not be created when hot reloading and therefore - the issue is solved. Code:Please consider
An issue that might pop up now is effeciency as database class instance is created for each request. This overhead can be reduced via Postgresql connection pooling (reusing db connections). Currently my database receives few enough connections to cause this error, so I will leave it for now.