Gunicorn: рдкреБрд░рд╛рдиреЗ рдмрдЧ рдХреЛ рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛я╝Ъ'рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛' рд╡рд╕реНрддреБ рдореЗрдВ websockets рдХреЗ рд╕рд╛рде wsgi.py рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рддрд╛ 'status_code' рдирд╣реАрдВ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 9 рдЕрдЧре░ 2018  ┬╖  33рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: benoitc/gunicorn

рдЗрд╕ рдкреБрд░рд╛рдиреЗ рдореБрджреНрджреЗ рдХреА рддрд░рд╣ рд╣реА 1210 рдиреЗ рдХрд╣рд╛, рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рд╣реЛрдиреЗ рдкрд░ рдЧрдирд┐рдХреЛрд░реНрди рддреНрд░реБрдЯрд┐ рд▓реЙрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдореЗрд░рд╛ рд╡рд╛рддрд╛рд╡рд░рдг рд╣реИя╝Ъ

  • рдбреЗрдмрд┐рдпрди рдЬреАрдПрдирдпреВ/рд▓рд┐рдирдХреНрд╕ 7.8

  • nginx

  • рдкрд╛рдпрдерди 3.4

  • Gunicorn(19.8.1) (рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЗ рд╕рд╛рде)

  • рдлреНрд▓рд╛рд╕реНрдХ-рд╕реЙрдХреЗрдЯрд┐рдпреЛ, рдХреНрд▓рд╛рдЗрдВрдЯ рд╡реЗрдмрд╕реЛрдХреЗрдЯ рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ

рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╣рд┐рдд рд╕рдм рдХреБрдЫ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рддреНрд░реБрдЯрд┐ рд▓реЙрдЧ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рджреЛ рдХреНрд▓рд╛рдЙрдб рд╕реНрд╡рддрдВрддреНрд░ рдЙрддреНрдкрд╛рджрди рдЙрджрд╛рд╣рд░рдг рджреЛрдиреЛрдВ рд▓рдЧрд╛рддрд╛рд░ рд▓реЙрдЧ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рдЕрдкрдиреА рд╡рд┐рдХрд╕рд┐рдд рдорд╢реАрди рдореЗрдВ рдкреБрди: рдкреЗрд╢ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдЬреЛ рдПрдХ рдореИрдХ рд╣реИред

рдЖрдкрдХреА рдорджрдж рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред

рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ /socket.io/?EIO=3&transport=websocket
рдЯреНрд░реЗрд╕рдмреИрдХ (рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдХреЙрд▓ рдЕрдВрддрд┐рдо):
рдлрд╝рд╛рдЗрд▓ "/opt/apps/lms/virtualenv/lib/python3.4/site-packages/gunicorn/workers/async.py", рд▓рд╛рдЗрди 56, рд╣реИрдВрдбрд▓ рдореЗрдВ
self.handle_request (рд╢реНрд░реЛрддрд╛_рдирд╛рдо, рдЕрдиреБрд░реЛрдз, рдЧреНрд░рд╛рд╣рдХ, рдпреЛрдЬрдХ)
рдлрд╝рд╛рдЗрд▓ "/opt/apps/lms/virtualenv/lib/python3.4/site-packages/gunicorn/workers/async.py", рд▓рд╛рдЗрди 116, рд╣реИрдВрдбрд▓_рд░реЗрдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ
рд╕рдореНрдорд╛рдиред рдмрдВрдж рдХрд░реЗрдВ ()
рдлрд╝рд╛рдЗрд▓ "/opt/apps/lms/virtualenv/lib/python3.4/site-packages/gunicorn/http/wsgi.py", рд▓рд╛рдЗрди 409, рдкрд╛рд╕ рдореЗрдВ
рд╕реНрд╡.рднреЗрдЬреЗрдВ_рд╣реЗрдбрд░ ()
рдлрд╝рд╛рдЗрд▓ "/opt/apps/lms/virtualenv/lib/python3.4/site-packages/gunicorn/http/wsgi.py", рд▓рд╛рдЗрди 325, send_headers рдореЗрдВ
tosend = self.default_headers ()
рдлрд╝рд╛рдЗрд▓ "/opt/apps/lms/virtualenv/lib/python3.4/site-packages/gunicorn/http/wsgi.py", рд▓рд╛рдЗрди 306, default_headers рдореЗрдВ
elif рд╕реНрд╡рдпрдВ. рдЪрд╛рд╣рд┐рдП_рдХреНрд▓реЛрдЬрд╝ ():
рдлрд╝рд╛рдЗрд▓ "/opt/apps/lms/virtualenv/lib/python3.4/site-packages/gunicorn/http/wsgi.py", рд▓рд╛рдЗрди 229, should_close рдореЗрдВ
рдЕрдЧрд░ self.status_code <200 рдпрд╛ self.status_code рдЗрди (204, 304):
рд╡рд┐рд╢реЗрд╖рддрд╛ рддреНрд░реБрдЯрд┐: 'рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛' рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рд╣реИ 'status_code'

Feedback Requested unconfirmed ThirdPartFlask

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдЯрдХреНрдХрд░ @benoitc

рд╕рднреА 33 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЗрд╕реЗ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЖрд╕рд╛рди рдЙрджрд╛рд╣рд░рдг рд╣реИ? рдХреГрдкрдпрд╛ рдпрджрд┐ рд╕рдВрднрд╡ рд╣реЛ рддреЛ рдирд╡реАрдирддрдо рдорд╛рд╕реНрдЯрд░ рдХреЗ рд╕рд╛рде рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдкрд╣рд▓реЗ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд╕реНрдерд╛рдиреАрдп рд╡рд┐рдХрд╛рд╕ рдкрд░реНрдпрд╛рд╡рд░рдг рдореЗрдВ рдХрдИ рдмрд╛рд░ рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ, рдЬреЛ рдЙрддреНрдкрд╛рджрди рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рдкреБрди: рдкреЗрд╢ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред

рдФрд░ рдореИрдВрдиреЗ рд╕рдВрд╕реНрдХрд░рдг 19.9.0 рд░рд┐рд▓реАрдЬрд╝ рд▓реЙрдЧ рдХреА рдЬрд╛рдБрдЪ рдХреА рд╣реИя╝МрдХреБрдЫ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рдорд┐рд▓рд╛я╝МрдореИрдВ рд░рдЦреВрдБрдЧрд╛
рдЗрд╕ рддреНрд░реБрдЯрд┐ рд▓реЙрдЧ рдХреЛ рджреЗрдЦ рд░рд╣реЗ рд╣реИрдВ, рдЕрдЧрд░ рдХреБрдЫ рдирдпрд╛ рдорд┐рд▓ рдЬрд╛рдП рддреЛ рдореИрдВ рдпрд╣рд╛рдВ рдкреЛрд╕реНрдЯ рдХрд░реВрдВрдЧрд╛ред

рдореБрдЭреЗ рднреА рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рдореИрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рд╡реЗрдмрд╕реЛрдХреЗрдЯ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕рднреА рдХрдиреЗрдХреНрд╢рди рдХреЛ рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реВрдВред рдореЗрд░реА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ BoWuGit рдЬреИрд╕реА рд╣реА рд╣реИрдВред рдпрджрд┐ рдЙрдиреНрдирдпрди рд╕реЗ рдкрд╣рд▓реЗ рдорддрджрд╛рди рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИ, рддреЛ рдпрд╣ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдФрд░ рддреНрд░реБрдЯрд┐ рд╣реИ:
`
[рддреНрд░реБрдЯрд┐] рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ /socket.io/?EIO=3&transport=polling&t=MPRHUoV&sid=cd64be7c940e474d8728b114c3fb9bbe

рдЯреНрд░реЗрд╕рдмреИрдХ (рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдХреЙрд▓ рдЕрдВрддрд┐рдо):
рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/gunicorn/workers/async.py", рд▓рд╛рдЗрди 56, рд╣реИрдВрдбрд▓ рдореЗрдВ
self.handle_request (рд╢реНрд░реЛрддрд╛_рдирд╛рдо, рдЕрдиреБрд░реЛрдз, рдЧреНрд░рд╛рд╣рдХ, рдпреЛрдЬрдХ)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/gunicorn/workers/async.py", рд▓рд╛рдЗрди 107, рд╣реИрдВрдбрд▓_рд░реЗрдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ
рд░реЗрд╕реНрдкрд┐рдЯрд░ = self.wsgi (рдкрд░реНрдпрд╛рд╡рд░рдг, resp.start_response)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/flask/app.py", рд▓рд╛рдЗрди 1994, __call__ рдореЗрдВ
рд╡рд╛рдкрд╕реА self.wsgi_app (рдкрд░реНрдпрд╛рд╡рд░рдг, start_response)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/flask_socketio/__init__.py", рд▓рд╛рдЗрди 43, __call__ рдореЗрдВ
start_response)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/engineio/middleware.
py", рд▓рд╛рдЗрди 47, __call__ рдореЗрдВ
рд╡рд╛рдкрд╕реА self.engineio_app.handle_request(environ, start_response)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/socketio/server.py", рд▓рд╛рдЗрди 360, рд╣реИрдВрдбрд▓_рд░реЗрдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ
рд╡рд╛рдкрд╕реА self.eio.handle_request(environ, start_response)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/engineio/server.py", рд▓рд╛рдЗрди 279, рд╣реИрдВрдбрд▓_рд░реЗрдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ
рд╕реЙрдХреЗрдЯ = рд╕реНрд╡рдпрдВ._get_socket (рдПрд╕рдЖрдИрдбреА)

рдлрд╝рд╛рдЗрд▓ "/usr/local/lib/python3.6/site-packages/engineio/server.py", рд▓рд╛рдЗрди 439, _get_socket рдореЗрдВ
KeyError рдмрдврд╝рд╛рдПрдБ ('рд╕рддреНрд░ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реИ')
`
рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдХреБрдЫ рд▓реЗрдирд╛-рджреЗрдирд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╡реЗрдмрд╕реНрдХреЗрдЯ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реВрдВ, рдпрд╣ рддреНрд░реБрдЯрд┐ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рджреЗрдЦреА рдЧрдИ рд╣реИред

рдЗрд╡реЗрдВрдЯрд▓реЗрдЯ 0.24.1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЧрдирд┐рдХреЛрд░реНрди 19.9.0 рдФрд░ рдлреНрд▓рд╛рд╕реНрдХ-рд╕реЙрдХреЗрдЯрд┐рдпреЛ 3.0.2 рдХреЗ рд╕рд╛рде рднреА рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реЛрдирд╛

рд╡рд┐рд╢реЗрд╖рддрд╛ рддреНрд░реБрдЯрд┐: 'рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛' рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рд╣реИ 'status_code'

рдирд┐рдореНрди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рднреА рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝ рд░рд╣рд╛ рд╣реИ:

Flask==1.0.2
gunicorn==19.5.0
python-socketio==2.0.0
eventlet==0.24.1

рдЦреБрд▓реЗ рд╕реЙрдХреЗрдЯ рдХрдиреЗрдХреНрд╢рди рд╡рд╛рд▓реЗ рд╡реЗрдм рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░рддреЗ рд╕рдордп рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢:

 Error handling request /socket.io/?EIO=3&transport=websocket&sid=d43ec0ae0bb946debc51f1ca2e5b8a94
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/gunicorn/workers/async.py", line 52, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/usr/lib/python2.7/dist-packages/gunicorn/workers/async.py", line 114, in handle_request
    resp.close()
  File "/usr/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 403, in close
    self.send_headers()
  File "/usr/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 319, in send_headers
    tosend = self.default_headers()
  File "/usr/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 300, in default_headers
    elif self.should_close():
  File "/usr/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 233, in should_close
    if self.status_code < 200 or self.status_code in (204, 304):
AttributeError: 'Response' object has no attribute 'status_code'

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЕрдЬрдЧрд░-рдЗрдВрдЬреАрдирд┐рдпреЛ рдХреЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдареАрдХ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ..

рдкрд╛рдпрдерди-рдЗрдВрдЬреАрдирд┐рдпреЛ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг (2.3.2) рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рд╣реИ, рдлрд┐рд░ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдХреЛрдИ рдЦрдмрд░? рд╕рдВрддрд░реА-рдЕрдЬрдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдореБрдЭреЗ рд╡рд╣реА рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ

рдореЗрд░реЗ рд╕рд╛рде рднреА рд╡рд╣реА рджрд┐рдХреНрдХрдд рд╣реИ

рдШрдЯрдирд╛: 0.25.1
рдлреНрд▓рд╛рд╕реНрдХ-рд╕реЙрдХреЗрдЯрд┐рдпреЛ: 4.2.1
рдЧрдирд┐рдХреЛрд░реНрди: 19.9.0

image

image

рдЗрд╕реЗ рдХреИрд╕реЗ рдкреБрди: рдкреЗрд╢ рдХрд░реЗрдВ? cna рдЖрдк рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ?

рдореБрдЭреЗ рдпрд╣ рднреА рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдкреБрди: рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛рдП, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдЕрдХреНрд╕рд░ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдореИрдВ рдЕрдкрдиреЗ рдЧрдирд┐рдХреЛрд░реНрди рдРрдк рдкрд░ рдПрдХ рдкреЗрдЬ рд░реАрдлреНрд░реЗрд╢ рдХрд░рддрд╛ рд╣реВрдВ

рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░реЗрдВ, рдФрд░ рдореЗрд░рд╛ рд╡рд╛рддрд╛рд╡рд░рдг @eazow рдЬреИрд╕рд╛ рд╣реА рд╣реИ рдЬрдмрдХрд┐ gunicorn == 20.0.4ред
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрдЧ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рдВрддрд░реА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реБрдИред
рдореБрджреНрджреЛрдВ рдХреЛ рджреНрд╡рд╛рд░рд╛ рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

  1. рдкреГрд╖реНрда рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░рдирд╛ (рдирдпрд╛ рдкреГрд╖реНрда рдирд╣реАрдВ рдЦреЛрд▓рдирд╛)
  2. рдкреЗрдЬ рдмрдВрдж рдХрд░рдирд╛

рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдПрдХ рдирдпрд╛ рдкреГрд╖реНрда рдЦреЛрд▓рдиреЗ рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рд╣реЛрдЧреАред рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпреЛрдВред рдзрдиреНрдпрд╡рд╛рдж!

рдореЗрд░реЗ рдкрд╛рд╕ @cowbonlin рдЬреИрд╕рд╛ рд╣реА рдореБрджреНрджрд╛ рд╣реИред рд╡рд╣реА рдЧрдирд┐рдХреЛрд░реНрди рд╕рдВрд╕реНрдХрд░рдг рднреАред

рд╕рдВрддрд░реА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХреА рдкрд╛рдЧрд▓ рдорд╛рддреНрд░рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрд╣ рдмрддрд╛рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рд╣реЛрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ - рдЪреВрдВрдХрд┐ рд╣рдордиреЗ рд╕рдВрддрд░реА рд╕реЗ рдкрд╣рд▓реЗ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛ред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдЯрди рд╕реНрдкреИрдо рд╣реИред

рд╣рдо рд╡рд╣реА рдЕрдиреБрднрд╡ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╕рдВрддрд░реА рд╕реНрдерд╛рдкрд┐рдд рд▓реЗрдХрд┐рди рдЕрдХреНрд╖рдоред рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?

рд╕рдВрддрд░реА рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдореБрджреНрджрд╛ рд╕реНрдерд╛рдкрд┐рддред

рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ рдЗрд╕реЗ рд╕рдВрддрд░реА (рдЕрдХреНрд╖рдо рдпрд╛ рдирд╣реАрдВ) рдХреЗ рдмрд┐рдирд╛ рдкреБрди: рдкреЗрд╢ рдХрд░рддрд╛ рд╣реИ?

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдирд╛рдорд╕реНрдерд╛рди рдХреЗ рдмрдЬрд╛рдп рдореИрдВрдиреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ/рдПрдкреАрдЖрдИ рдорд╛рд░рд╛ред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдирд╛рдорд╕реНрдерд╛рди рдХреЗ рдмрдЬрд╛рдп рдореИрдВрдиреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ/рдПрдкреАрдЖрдИ рдорд╛рд░рд╛ред

рдЗрд╕рдХрд╛ рдорддрд▓рдм рдХреНрдпрд╛ рд╣реИ ? рдХреНрдпрд╛ рдпрд╣ рд╕рдВрддрд░реА рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ?

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдирд╛рдорд╕реНрдерд╛рди рдХреЗ рдмрдЬрд╛рдп рдореИрдВрдиреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ/рдПрдкреАрдЖрдИ рдорд╛рд░рд╛ред

рдЗрд╕рдХрд╛ рдорддрд▓рдм рдХреНрдпрд╛ рд╣реИ ? рдХреНрдпрд╛ рдпрд╣ рд╕рдВрддрд░реА рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ?

рдирд╣реАрдВ, рдпрд╣ socket.io рдиреЗрдорд╕реНрдкреЗрд╕ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рд╣рдЯрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рдж рднреА, рдореБрдЭреЗ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИред рдореБрдЭреЗ рдпрд╣ рдЕрдиреНрдп рддреНрд░реБрдЯрд┐ рд╕реНрдерд╛рдиреАрдп рдорд╢реАрди рдкрд░ рдмрд┐рдирд╛ рдЧрдирд┐рдХреЛрд░реНрди рдпрд╛ nginx рдХреЗ рдорд┐рд▓рддреА рд╣реИ, рдЬреЛ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛ рд╕рдХрддреА рд╣реИред

рдпреЗ рдореЗрд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВ:

sentry_sdk == 0.14.3
Flask_SocketIO == 4.2.1
eventlet == 0.25.1

рдпрд╣ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдореЗрд░рд╛ рдХреБрдкреНрдкреА-рд╕реЙрдХреЗрдЯрд┐рдпреЛ рдХреЛрдб рд╣реИ:

socketio = SocketIO(engineio_logger=True, logger=True, debug=True, cors_allowed_origins="*", path='/socket.io')
...
socketio.init_app(app, async_mode="eventlet")

рдФрд░ рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рдореЗрд░рд╛ рд░рд┐рдПрдХреНрдЯ рд╕реЙрдХреЗрдЯ io рдХреЛрдб рд╣реИ:

          this.socket = io.connect(`http://localhost:5000?info=${someInfo}`, {
            transports: ['websocket', 'polling'] // an attempt to keep polling as a fallback but start on websockets
          });

рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХреНрдпрд╛ рдЗрд╕рд╕реЗ рдорджрдж рдорд┐рд▓рддреА рд╣реИред рдЙрдмрдВрдЯреВ рдкрд░ рддреНрд░реБрдЯрд┐ рдЙрдкрд░реЛрдХреНрдд рдХреА рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ, рдФрд░ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рд╡рд┐рдВрдбреЛрдЬрд╝ рдкрд░ рдРрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:
``` рдЯреНрд░реЗрд╕рдмреИрдХ (рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдХреЙрд▓ рдЕрдВрддрд┐рдо):
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 599, handle_one_response рдореЗрдВ
рд▓рд┐рдЦреЗрдВ (рдмреА '')
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 491, рд▓рд┐рдЦрд┐рдд рдореЗрдВ
AssertionError ("рд▓рд┐рдЦреЗрдВ () start_response ()") рд╕реЗ рдкрд╣рд▓реЗ рдмрдврд╝рд╛рдПрдВ
рдЕрднрд┐рдХрдерди рддреНрд░реБрдЯрд┐: start_response () рд╕реЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦреЗрдВ ()

рдЙрдкрд░реЛрдХреНрдд рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рджреМрд░рд╛рди, рдПрдХ рдФрд░ рдЕрдкрд╡рд╛рдж рд╣реБрдЖ:

рдЯреНрд░реЗрд╕рдмреИрдХ (рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдХреЙрд▓ рдЕрдВрддрд┐рдо):
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 357, __init__ рдореЗрдВ
рд╕реНрд╡рдпрдВ рд╕рдВрднрд╛рд▓ ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 390, рд╣реИрдВрдбрд▓ рдореЗрдВ
self.handle_one_request ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 466, рд╣реИрдВрдбрд▓_рдСрди_рд░реЗрдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ
self.handle_one_response ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 609, handle_one_response рдореЗрдВ
рд▓рд┐рдЦреЗрдВ (рдЧрд▓рддреА_рдмреЙрдбреА)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 538, рд▓рд┐рдЦрд┐рдд рдореЗрдВ
wfile.flush ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\socket.py", рд▓рд╛рдЗрди 607, рд▓рд┐рдЦрд┐рдд рдореЗрдВ
рд╕реНрд╡._рд╕реЙрдХ.рднреЗрдЬреЗрдВ (рдмреА)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\greenio\base.py", рд▓рд╛рдЗрди 397, рднреЗрдЬрдиреЗ рдореЗрдВ
рд╕реНрд╡._send_loop (self.fd.send, рдбреЗрдЯрд╛, рдЭрдВрдбреЗ) рд╡рд╛рдкрд╕ рдХрд░реЗрдВ
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\greenio\base.py", рд▓рд╛рдЗрди 384, _send_loop рдореЗрдВ
рд╡рд╛рдкрд╕реА send_method (рдбреЗрдЯрд╛, * args)
ConnectionAbortedError: [WinError 10053] рдПрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрдиреЗрдХреНрд╢рди рдЖрдкрдХреЗ рд╣реЛрд╕реНрдЯ рдорд╢реАрди рдореЗрдВ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░рд╕реНрдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛

рдЙрдкрд░реЛрдХреНрдд рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рджреМрд░рд╛рди, рдПрдХ рдФрд░ рдЕрдкрд╡рд╛рдж рд╣реБрдЖ:

рдЯреНрд░реЗрд╕рдмреИрдХ (рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдХреЙрд▓ рдЕрдВрддрд┐рдо):
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\hubs\hub.py", рд▓рд╛рдЗрди 461, fire_timers рдореЗрдВ
рдЯрд╛рдЗрдорд░ ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\hubs\timer.py", рд▓рд╛рдЗрди 59, __call__ рдореЗрдВ
рд╕реАрдмреА ( рддрд░реНрдХ, * рдХрд┐рд▓реЛрд╡рд╛рдЯ)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\semaphore.py", рд▓рд╛рдЗрди 147, _do_acquire рдореЗрдВ
рд╡реЗрдЯрд░.рд╕реНрд╡рд┐рдЪ ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\greenthread.py", рд▓рд╛рдЗрди 221, рдореБрдЦреНрдп рдореЗрдВ
рдкрд░рд┐рдгрд╛рдо = рдлрд╝рдВрдХреНрд╢рди ( рддрд░реНрдХ, * kwargs)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 818, process_request рдореЗрдВ
рдЖрджреНрдп.__init__(conn_state, рд╕реНрд╡рдпрдВ)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 359, __init__ рдореЗрдВ
рд╕реНрд╡рдпрдВ рд╕рдорд╛рдкреНрдд ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\wsgi.py", рд▓рд╛рдЗрди 732, рдЕрдВрдд рдореЗрдВ
рдмреЗрд╕рдПрдЪрдЯреАрдЯреАрдкреАрд╕рд░реНрд╡рд░.рдмреЗрд╕рдПрдЪрдЯреАрдЯреАрдкреАрдЕрдиреБрд░реЛрдзрд╣реИрдВрдбрд▓рд░.рдлрд┐рдирд┐рд╢(рд╕реНрд╡рдпрдВ)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\socketserver.py", рд▓рд╛рдЗрди 784, рдЕрдВрдд рдореЗрдВ
рд╕реНрд╡рдпрдВ.wfile.рдмрдВрдж рдХрд░реЗрдВ ()
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\socket.py", рд▓рд╛рдЗрди 607, рд▓рд┐рдЦрд┐рдд рдореЗрдВ
рд╕реНрд╡._рд╕реЙрдХ.рднреЗрдЬреЗрдВ (рдмреА)
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\greenio\base.py", рд▓рд╛рдЗрди 397, рднреЗрдЬрдиреЗ рдореЗрдВ
рд╕реНрд╡._send_loop (self.fd.send, рдбреЗрдЯрд╛, рдЭрдВрдбреЗ) рд╡рд╛рдкрд╕ рдХрд░реЗрдВ
рдлрд╝рд╛рдЗрд▓ "C:\ProgramData\Anaconda3\lib\site-packages\eventlet\greenio\base.py", рд▓рд╛рдЗрди 384, _send_loop рдореЗрдВ
рд╡рд╛рдкрд╕реА send_method (рдбреЗрдЯрд╛, * args)
ConnectionAbortedError: [WinError 10053] рдПрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрдиреЗрдХреНрд╢рди рдЖрдкрдХреЗ рд╣реЛрд╕реНрдЯ рдорд╢реАрди рдореЗрдВ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░рд╕реНрдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ```

рдкреБрд╖реНрдЯрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрддрд░реА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░ рдпрд╣ рддреНрд░реБрдЯрд┐ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИред рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЧрдирд┐рдХреЛрд░реНрди рдЗрд╕рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдордЬрдмреВрдд рд╣реЛред

рдЯрдХреНрдХрд░ @benoitc

рдкреБрд╖реНрдЯрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрддрд░реА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░ рдпрд╣ рддреНрд░реБрдЯрд┐ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИред рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЧрдирд┐рдХреЛрд░реНрди рдЗрд╕рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдордЬрдмреВрдд рд╣реЛред

рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ рд╕рдВрддрд░реА рдХреЗ FlaskIntegration рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рд╕реЗ рднреА рддреНрд░реБрдЯрд┐ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИред

рдЗрд╕реА рддрд░рд╣ рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рджреЗрдЦрдирд╛ред рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдирдП рдЕрд╡рд╢реЗрд╖ рдХрд╛ рдЙрдкрдпреЛрдЧ рдлреНрд▓рд╛рд╕реНрдХ-рд╕реЙрдХреЗрдЯрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рд╡рд┐рдХрд╛рд╕ рдореЗрдВ, рдХреБрдкреНрдкреА-рд╕реЙрдХреЗрдЯрд┐рдпреЛ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╡рд░реНрдХрдЬрд╝реЗрдЧ рдбрд┐рдмрдЧрд░ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЗрдВрдЬрд┐рдирд┐рдпреЛ рдХреЗ wsgi рдРрдк рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ)ред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЙрддреНрдкрд╛рджрди рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░рд┐рдкрд┐рдВрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ред

Gunicorn config рдХреЗ post_request рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдПрдХ рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдХреЛ resp.status_code рдкрд░ рдЬрд╝рдмрд░рджрд╕реНрддреА рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдирд╣реАрдВ рд▓рд┐рдпрд╛ред

рдпрд╣ рддреНрд░реБрдЯрд┐ Gunicorn рдФрд░ Flask-SocketIO рдХреЗ рд╕рд╛рде рд╕рдВрддрд░реА рдХреЗ FlaskIntegration рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдХреНрдпрд╛ рдЬрд▓реНрдж рд╣реА рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╕рдВрднрд╡ рд╣реИ?

@Canicio рд╣рдордиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рддреНрд░реБрдЯрд┐ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдПрдХреАрдХрд░рдг рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рднреА рддреНрд░реБрдЯрд┐ рдмрдиреА рд░рд╣рддреА рд╣реИред

рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЗ рдкрд╛рд╕ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХреЛрдб/ @benoitc рдХреЗ рд▓рд┐рдП рдПрдХ рдиреНрдпреВрдирддрдо рдЙрджрд╛рд╣рд░рдг рд╣реИ?

рдЬрд╝рд░реВрд░:

import sentry_sdk
from flask import Flask
from flask_socketio import SocketIO
from sentry_sdk.integrations.flask import FlaskIntegration

sentry_sdk.init(
    dsn="https://[email protected]/0",
    integrations=[FlaskIntegration()]
)

app = Flask(__name__)
socketio = SocketIO(app)

@app.route('/')
def index():
    return '''
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
    var socket = io()
</script>

рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ:

flask
sentry-sdk[flask]
flask-socketio
eventlet

рдЙрджрд╛рд╣рд░рдг рдЧрдирд┐рдХреЛрд░реНрди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди:

bind = '[::]:4444'
worker_class = 'eventlet'
accesslog = '-'

/ рд▓реЛрдб рд╣реЛрдиреЗ рдкрд░ рдпрд╣ рд╡реЗрдмрд╕реЛрдХреЗрдЯ рд╕реЗ рдЬреБрдбрд╝ рдЬрд╛рдПрдЧрд╛ред рд╡реЗрдмрд╕реЛрдХреЗрдЯ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдкрд░ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рджреВрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░реЗрдВ, рд░реАрдлреНрд░реЗрд╢ рдХрд░реЗрдВ), рдЗрд╕ рддрд░рд╣ рдЕрдкрд╡рд╛рдж рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛:

[2020-09-23 07:24:49 +0000] [16303] [ERROR] Error handling request /socket.io/?EIO=3&transport=websocket&sid=29f4c1adfac343d6bc6db56acf8fd0ee
Traceback (most recent call last):
  File "/home/ziddey/projects/sentry/venv_sentry/lib/python3.8/site-packages/gunicorn/workers/base_async.py", line 55, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/home/ziddey/projects/sentry/venv_sentry/lib/python3.8/site-packages/gunicorn/workers/base_async.py", line 115, in handle_request
    resp.close()
  File "/home/ziddey/projects/sentry/venv_sentry/lib/python3.8/site-packages/gunicorn/http/wsgi.py", line 402, in close
    self.send_headers()
  File "/home/ziddey/projects/sentry/venv_sentry/lib/python3.8/site-packages/gunicorn/http/wsgi.py", line 318, in send_headers
    tosend = self.default_headers()
  File "/home/ziddey/projects/sentry/venv_sentry/lib/python3.8/site-packages/gunicorn/http/wsgi.py", line 299, in default_headers
    elif self.should_close():
  File "/home/ziddey/projects/sentry/venv_sentry/lib/python3.8/site-packages/gunicorn/http/wsgi.py", line 219, in should_close
    if self.status_code < 200 or self.status_code in (204, 304):
AttributeError: 'Response' object has no attribute 'status_code'
2001:470:1f07:7eb:9dd4:254c:35d7:236c - - [23/Sep/2020:07:24:49 +0000] "GET /socket.io/?EIO=3&transport=websocket&sid=29f4c1adfac343d6bc6db56acf8fd0ee HTTP/1.1" 500 0 "-" "-"

рдиреЛрдЯ: рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрд╡рдпрдВ рдХрднреА рд╕рдВрддрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдпрд╣ рд╕рд┐рд░реНрдл рд╕рдВрддрд░реА рдХреЗ рдЖрд░рдВрднрд┐рдХ рдкреГрд╖реНрда рд╕реЗ рд╣реИред рдЙрджрд╛рд╣рд░рдг dsn рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

integrations=[FlaskIntegration()] рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рд╕реЗ рддреНрд░реБрдЯрд┐ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧреА (рдмреЗрд╢рдХ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рд╕рдВрддрд░реА рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдирд╛)ред

рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рдХреНрдпрд╛ рд╣реИ, рдмрд┐рдирд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдЗрд╡реЗрдВрдЯрд▓реЗрдЯ рдХреЗ рдмрдЬрд╛рдп gevent-websocket рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ ..

рдареАрдХ рд╣реИ, рдХреБрдЫ рдЦреЗрд▓ рд░рд╣рд╛ рдерд╛ред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрддрд░реА/рдиреНрдпреВрд░реЗрд▓рд┐рдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд▓рдкреЗрдЯрддрд╛ рд╣реИред рд╕рдВрддрд░реА рдХреЗ рдмрд┐рдирд╛, рд╣рдореЗрдВ рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ <eventlet.wsgi._AlreadyHandled object at 0x7fd0f5b1c0d0> рдорд┐рд▓рддрд╛ рд╣реИ рдФрд░ рдЧрдирд┐рдХреЛрд░реНрди рдХрд╛ EventletWorker.is_already_handled() рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рдВрддрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рдЪреЗрдХ рдореЗрдВ рд╡рд┐рдлрд▓ рд╣реЛрдиреЗ рдХреЗ рдмрдЬрд╛рдп <sentry_sdk.integrations.wsgi._ScopedResponse object at 0x7f30155a5100> рдЬреИрд╕рд╛ рдХреБрдЫ рдмрди рдЬрд╛рддрд╛ рд╣реИ

рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд░реЗрд╕реНрдкрд┐рдЯрд░ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдЦрд╛рд▓реА рд╣реИред рдХрд▓ рдЖрдЧреЗ рджреЗрдЦреЗрдВрдЧреЗред

рдареАрдХ рд╣реИ, рдпрд╣рд╛рдБ рд╡рд╣ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореИрдВ рдЖрдпрд╛ рд╣реВрдБ:

eventlet_fix.py:
рдиреАрдЪреЗ рд╕рдВрдкрд╛рджрд┐рдд рджреЗрдЦреЗрдВ

рдФрд░ рдореЗрд░реЗ рдЧрдирд┐рдХреЛрд░реНрди рдореЗрдВ config.py: worker_class = 'eventlet_fix.EventletWorker ред

рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрддрд░реА/рдиреНрдпреВрд░реЗрд▓рд┐рдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдИрд╡реЗрдВрдЯрд▓реЗрдЯ рдХреЗ ALREADY_HANDLED рдХреЗ рд╡рд┐рд░реБрджреНрдз рдЖрд╕рд╛рдиреА рд╕реЗ рдЬрд╛рдВрдЪ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╣реИрдВрдбрд▓ рдХрд┐рдП рдЧрдП рдЕрдиреБрд░реЛрдз рдХреА рдкреНрд░рдХреГрддрд┐ рдпрд╣ рд╣реИ рдХрд┐ рдЧрдирд┐рдХреЛрд░реНрди рдХреЗ start_response рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рдо рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрдерд┐рддрд┐ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП wsgi рдХреЙрд▓ рдХреЛ рд╣рд╛рдИрдЬреИрдХ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдорд╛рдиреЛрдВ рдХреЛ рд╣реИрдХ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИред рдпрд╣ рдЕрдиреБрд░реЛрдз рдХреЛ рдЕрднреА рднреА gunicorn рджреНрд╡рд╛рд░рд╛ рд▓реЙрдЧ рдЗрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдпрд╣ рдореВрд▓ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп StopIteration рдХреЛ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

101 рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╣реИрдХ рдХрд░рдирд╛ рд╣рдорд╛рд░реЗ рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ (рдлреНрд▓рд╛рд╕реНрдХ-рд╕реЙрдХреЗрдЯрд┐рдпреЛ рд╡реЗрдмрд╕реЛрдХреЗрдЯ) рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреНрдпрдерд╛, рдЗрд╕реЗ рдЫреЛрдбрд╝рдХрд░ рдХреЛрдИ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ headers_sent рдФрд░ should_close рдХреЛ рдЯреНрд░реВ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдлрд┐рд░, рдпрд╣ рдзрд╛рд░рдгрд╛ рдмрдирд╛рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ status рд╕реЗрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ start_response рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХреЛ рдмрд╛рд╣рд░реА рд░реВрдк рд╕реЗ "рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдВрднрд╛рд▓рд╛" рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВред рдкреБрдирд░реНрдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ, рддреЛ $ resp.status start_response рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ 2: рд╣реИрдХ рдХрд┐рдП рдЧрдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЗрдЯрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

from functools import wraps

from gunicorn.workers.geventlet import EventletWorker as _EventletWorker


class HackedResponse:
    def __init__(self, respiter, resp):
        self.respiter = iter(respiter)
        self.resp = resp
        if hasattr(respiter, "close"):
            self.close = respiter.close

    def __iter__(self):
        return self

    def __next__(self):
        try:
            return next(self.respiter)
        except StopIteration:
            if not self.resp.status:
                self.resp.status = "101"  # logger derives status code from status instead of using status_code
                self.resp.status_code = 101  # not actually needed since headers_sent/force_close result in status_code not being checked anymore
                self.resp.headers_sent = True
                self.resp.force_close()
            raise


def wsgi_decorator(wsgi):
    @wraps(wsgi)
    def wrapper(environ, start_response):
        respiter = wsgi(environ, start_response)
        resp = start_response.__self__
        return HackedResponse(respiter, resp)

    return wrapper


class EventletWorker(_EventletWorker):
    def load_wsgi(self):
        super().load_wsgi()
        self.wsgi = wsgi_decorator(self.wsgi)

рдЬрд╛рд╣рд┐рд░ рд╣реИ рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдмрдВрджрд░ рдкреИрдЪ рд╣реИред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реБрдзрд╛рд░ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ base_async.py рдореЗрдВ handle_request рдореЗрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреБрдВрдЬреА (рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рд░реВрдк рд╕реЗ) рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛ рд╕рдХрддреА рд╣реИ рдХрд┐ start_response рдХреЛ respiter рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдХреЙрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдпрд╛ рддреЛ resp.status (рдХреЗрд╡рд▓ start_response рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдпрд╛ resp.headers_sent (рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВ рдХрд┐ рд╣рдордиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдиреБрд░реЛрдз рдХрд╛ рдЬрд╡рд╛рдм рджрд┐рдпрд╛ рд╣реИ)ред

@benoitc
@ziddy рдиреЗ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдвреВрдВрдв рд▓рд┐рдпрд╛ рд╣реИред

@ziddy рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рддреНрд╡рд░рд┐рдд рдкреНрд░рд╢реНрди (рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рд╕рдВрддрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ)ред

  • рдХреНрдпрд╛ рддреНрд░реБрдЯрд┐ рдХреЗрд╡рд▓ рд╕рдВрддрд░реА рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд░рд╣реА рд╣реИ рдпрд╛ рдЕрдиреБрд░реЛрдз рднреА рд░реЛрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╛рдиреА рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рд░рд╣рд╛ рд╣реИ (рдЬреЛ рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд▓рдкреЗрдЯреА рдЧрдИ рд╣реИ)?
  • рдХреНрдпрд╛ рдЖрдк рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡рд╣рд╛рдВ рдХреБрдЫ рд▓рдкреЗрдЯрд╛ рдЬрд╛рдП рдпрд╛ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рд╛рдл рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЕрдЧрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд▓рдкреЗрдЯреА рдЧрдИ рд╣реИ рддреЛ рдареАрдХ рд░рд╣реЗрдЧрд╛?

@benoitc рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди https://github.com/benoitc/gunicorn/issues/1852#issuecomment -697189261 рдФрд░ https://github.com/benoitc/gunicorn/blob/4ae2a05c37b332773997f90ba7542713b9bf8274/ Gunicorn/workers/base_async.py#L107 -L140

рдЖрдо рддреМрд░ рдкрд░, is_already_handled рд╕рдЪ рд▓реМрдЯреЗрдЧрд╛ рдФрд░ рдпрд╣ рдпрд╣реАрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрдЧрд╛ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд▓рд┐рдкрдЯреА рд╣реБрдИ рд╣реИ, рд╡рд╣ рд╡рд┐рдзрд┐ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдирд┐рд╖реНрдкрд╛рджрди рдЖрдЧреЗ рдмрдврд╝рддрд╛ рд╣реИ, рдкрдВрдХреНрддрд┐ 115 рдкрд░ рд╡рд┐рдлрд▓: resp.close() рд╣реЗрдбрд░ рднреЗрдЬрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди start_response рдХреЛ рдХрднреА рднреА рдХреЙрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдХреЛрдИ рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдирд╣реАрдВ рд╣реИред рдЕрдЧрд░ рдРрд╕рд╛ рдХрд┐рдпрд╛ рднреА, рддреЛ рднреА рдпрд╣ рдЕрдВрддрддрдГ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕реЗ handle_error рджреНрд╡рд╛рд░рд╛ рдкреБрди: рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдФрд░ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдЕрдиреБрд░реЛрдз рдкрд╣рд▓реЗ рд╣реА рдмрд╛рд╣рд░реА рд░реВрдк рд╕реЗ рд╕рдВрднрд╛рд▓рд╛ рдЬрд╛ рдЪреБрдХрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рд▓реЙрдЧ рд╕реНрдкреИрдо рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдпрд╣рд╛рдВ рдХреЛрдИ рдиреБрдХрд╕рд╛рди рдирд╣реАрдВ рд╣реИред

рдореИрдВ рд╕рдВрддрд░реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддрд╛-- рдореИрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдХ рд╡рд┐рд╡рд░рдг: рдореМрдЬреВрджрд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╕рдВрдЪрд╛рд▓рд┐рдд рддрдВрддреНрд░ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд▓реЙрдЧрд┐рдВрдЧ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЬрд╛рдирдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдмрд╛рд╣рд░реА рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рд╛ рдЧрдпрд╛ред рдореЗрд░реА рд╣реИрдХ рдХреА рдЧрдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдореИрдВ рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдХреЛ headers_sent рдХреЗ рд╕рд╛рде рд╕рддреНрдп рдХреЗ рд░реВрдк рдореЗрдВ 101 рдкрд░ рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реВрдВ рддрд╛рдХрд┐ рд╣реИрдВрдбрд▓рд░ рдЖрдЧреЗ рдмрдврд╝ рд╕рдХреЗ рдФрд░ рдЕрдиреБрд░реЛрдз рдЕрднреА рднреА рд▓реЙрдЧ рд╣реЛ рдЬрд╛рдПред

resp.status рдХреА рдЬрд╛рдБрдЪ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкрд░реАрдХреНрд╖рдг рд╣реИ рдХрд┐ start_response рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВред

@benoitc рдЗрд╕ рдкрд░ рджреЛрдмрд╛рд░рд╛ рдЧреМрд░ рдХрд░ рд░рд╣рд╛ рд╣реИред рдЕрдзрд┐рдХ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдХрд░реНрд╖ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЕрдиреБрд░реЛрдз рдкрд╣рд▓реЗ рд╣реА рд╕рдВрднрд╛рд▓рд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ, environ['gunicorn.socket'] рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░реЙрдХреНрд╕реА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣, рдЗрд╕реЗ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рд╕реЙрдХреЗрдЯ рдХреЛ рд╕реАрдзреЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдИрд╡реЗрдВрдЯрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП get_socket() рд▓рдкреЗрдЯрдирд╛), рдФрд░ is_already_handled рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

рдпрджрд┐ рдПрдХреНрд╕реЗрд╕ рд▓реЙрдЧрд┐рдВрдЧ рд╡рд╛рдВрдЫрд┐рдд рд╣реИ, рддреЛ рдЗрд╕реЗ рдЕрднреА рднреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╣реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

Bogdanp picture Bogdanp  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

haolujun picture haolujun  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mw44118 picture mw44118  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

benoitc picture benoitc  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

gr790 picture gr790  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ