uvicorn: Run uvicorn with multiple workers on Windows - WinError 87
Describe the bug Uvicorn doesn’t seem to be able to start with multiple workers.
Code snippet Starlette Hello World
import uvicorn as uvicorn
from starlette.applications import Starlette
from starlette.responses import JSONResponse
app = Starlette(debug=True)
@app.route('/')
async def homepage(request):
return JSONResponse({'hello': 'world'})
if __name__ == '__main__':
uvicorn.run(app, host='127.0.0.1', port=8000, workers=2)
Expected behavior
Uvicorn starts and is ready to serve with multiple workers.
Environment
Windows 10 Uvicorn: 0.6.1 Python: 3.7.2 Starlette: 0.11.4
Additional context
(venv) C:\Users\marodev\source\repos\StarletteHelloWorldVirtualEnvPy37>python main.py
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started parent process [35788]
Traceback (most recent call last):
File "main.py", line 14, in <module>
uvicorn.run(app, host='127.0.0.1', port=8000, workers=2)
File "C:\Users\marodev\source\repos\StarletteHelloWorldVirtualEnvPy37\venv\lib\site-packages\uvicorn\main.py", line 274, in run
supervisor.run(server.run, sockets=[socket])
File "C:\Users\marodev\source\repos\StarletteHelloWorldVirtualEnvPy37\venv\lib\site-packages\uvicorn\supervisors\multiprocess.py", line 33, in run
process.start()
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 112, in start
self._popen = self._Popen(self)
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
reduction.dump(process_obj, to_child)
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'request_response.<locals>.app'
(venv) C:\Users\marodev\source\repos\StarletteHelloWorldVirtualEnvPy37>Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\spawn.py", line 99, in spawn_main
new_handle = reduction.steal_handle(parent_pid, pipe_handle)
File "C:\Users\marodev\AppData\Local\Programs\Python\Python37\lib\multiprocessing\reduction.py", line 82, in steal_handle
_winapi.PROCESS_DUP_HANDLE, False, source_pid)
OSError: [WinError 87] The parameter is incorrect
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 38 (10 by maintainers)
The same issue with Python 3.9.10 and uvicorn 0.17.6.
Upgrading Uvicorn to “0.18.1” solved for me!
I believe the issue is related to the Python sockets lib on Windows. Windows effectively deadlocks a port during Python’s initial socket configuration. So if you have multiple python threads or interpreters attempting to start listening to a socket at once, you’ll get a
WinError.The consensus seems to be to use
sleepbetween each socket listener setup. This can also be used in conjunction with some sort of retry logic that catchesWinError@tomchristie Can you please provide an update?