Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flask + ProcessPoolExecutor -> TypeError: can't pickle _thread.lock objects #28

Open
codeape2 opened this issue Oct 15, 2020 · 2 comments

Comments

@codeape2
Copy link

  • Python version: 3.7.7 (default, Apr 15 2020, 05:09:04) [MSC v.1916 64 bit (AMD64)]
  • aiohttp: 3.6.2
  • aiohttp_wsgi: 0.8.2
  • flask: 1.1.2

To reproduce:

from concurrent.futures.process import ProcessPoolExecutor
from concurrent.futures.thread import ThreadPoolExecutor

from aiohttp import web
from aiohttp_wsgi import WSGIHandler
from flask import Flask


flaskapp = Flask(__name__)


@flaskapp.route('/')
def index():
    return 'hello from flask'


executor = ProcessPoolExecutor()  # ThreadPoolExecutor() works


aioapp = web.Application()
aioapp.router.add_route('*', '/{path_info:.*}', WSGIHandler(flaskapp, executor=executor))


if __name__ == '__main__':
    web.run_app(aioapp)

Traceback:

======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Error handling request
concurrent.futures.process._RemoteTraceback: 
"""
Traceback (most recent call last):
  File "F:\envs\_april\lib\multiprocessing\queues.py", line 236, in _feed
    obj = _ForkingPickler.dumps(obj)
  File "F:\envs\_april\lib\multiprocessing\reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "F:\envs\_april\lib\site-packages\aiohttp\web_protocol.py", line 418, in start
    resp = await task
  File "F:\envs\_april\lib\site-packages\aiohttp\web_app.py", line 458, in _handle
    resp = await handler(request)
  File "F:\envs\_april\lib\site-packages\aiohttp\web_urldispatcher.py", line 158, in handler_wrapper
    return await result
  File "F:\envs\_april\lib\site-packages\aiohttp_wsgi\wsgi.py", line 266, in handle_request
    environ,
  File "F:\envs\_april\lib\multiprocessing\queues.py", line 236, in _feed
    obj = _ForkingPickler.dumps(obj)
  File "F:\envs\_april\lib\multiprocessing\reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
@codeape2
Copy link
Author

A minimal wsgi app also fails:

def simplest_wsgi_app(environ, start_response):
    print(environ)
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return [b"hello from wsgi!\n"]

With TypeError: can't pickle _asyncio.Future objects

@codeape2
Copy link
Author

codeape2 commented Oct 15, 2020

The minimal wsgi app works if I use a modified WSGIHandler:

class MultiprocessCompatibleWSGIHandler(WSGIHandler):
    def _get_environ(self, request, body, content_length):
        environ = super()._get_environ(request, body, content_length)
        del environ['asyncio.loop']
        del environ['asyncio.executor']
        del environ['aiohttp.request']
        return environ

... but flask does not work. I guess serializing the entire flask application is not feasible. A possible approach for using a ProcessPool executor is to initialize the wsgi app in the process pool's initializer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant