Как добиться преимуществ параллелизма с помощью gevent (в сочетании с uwsgi)? - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь понять, как добиться асинхронных преимуществ, которые должна обеспечить gevent мартышка.

Чтобы проверить это, я создал тестовый сервер.

from gevent import monkey
monkey.patch_all()
from flask import Flask
from time import sleep
import requests

app = Flask(__name__)


def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)


@app.route('/')
def hello_world():
    return 'Hello, World!'


@app.route('/sleep/<int:n>')
def sleep_view(n):
    sleep(n)
    return f'Slept {n}'


@app.route('/slowreq')
def slowreq_view():
    res = requests.get('http://localhost:8002/sleep/5')
    return 'From another server: ' + res.text


@app.route('/fib/<int:n>')
def fib_view(n):
    x = fib(n)
    return str(x)


if __name__ == '__main__':
    import sys
    port = 8001
    threaded = False
    if len(sys.argv) > 1:
        port = int(sys.argv[1])
        threaded = True
    print(f'Threaded is {threaded}')
    app.run(port=port, threaded=threaded)

Если я запускаю его в двух процессах, сначала с python3 test.py (работает на 8001, колба не резьбовая, но исправлена ​​обезьяна), а затем python3 test.py 8002 (работает на 8002, колба резьбовая, также исправлена ​​обезьяна),Я ожидаю, что произойдет следующее:

  1. В двух терминалах я быстро запускаю time curl http://localhost:8001/slowreq один за другим./slowreq вызывает /sleep/5 на другом сервере, поэтому для отдельного запроса это должно занять 5 секунд.
  2. Сервер на 8001 получает запрос и вызывает сервер 8002 с помощью requests.get.Requests - это оболочка для urllib3, которая является оболочкой stdlib для socket, которая gevent.monkey.patch_all() исправляет по умолчанию (socket=True по умолчанию).Из-за мартовских патчей я ожидаю, что сервер будет ожидать ответа.
  3. Сервер 8002 получает запрос /sleep/5, спит в течение 5 секунд и отвечает.Поскольку это многопоточный сервер, одновременно может происходить несколько снов.

В случае, не являющемся пропатченным, я ожидаю, что первый запрос /slowreq займет 5 секунд, а второйчтобы занять 10 секунд, и это то, что я вижу.

Однако, в случае с пропатченной обезьяной, я ожидаю, что сервер 8001 больше не будет блокировать вызов requests.get, и поэтому оба запроса будут занимать 5секунд.Это не то, что происходит, и поведение идентично случаю, не пропатченному обезьянами.

Таким образом, мой вопрос: чего добивается исправление обезьяны и как я могу воспользоваться его преимуществами?

...