Как зациклить GET, пока не будет получен определенный ответ - PullRequest
0 голосов
/ 11 января 2019

Я ищу какой-нибудь совет или соответствующий учебник относительно следующего:

Моя задача состоит в том, чтобы установить маршрут фляги, который отправляет POST к API конечной точке X , получает в ответе новую конечную точку Y , затем получает GET от конечной точки Y до тех пор, пока не получит определенное сообщение о состоянии в теле ответа Y, а затем вернет ответ Y.

Код ниже (несущественные данные отредактированы) выполняет эту цель, я думаю, очень глупо. Иногда возвращает соответствующие данные, но не надежно. (Время ожидания истекает в 60% случаев.) Когда я очень тщательно консоль веду журнал, создается впечатление, что я перегружал свой сервер несколькими непрерывными циклами, мешающими друг другу.

Я также иногда получаю эту ошибку:

SIGPIPE: запись в закрытый канал / сокет / fd (возможно, клиент отключен) по запросу / книге

import sys, requests, time, json
from flask import Flask, request

# create the Flask app
app = Flask(__name__)

# main booking route
@app.route('/book', methods=['POST']) #GET requests will be blocked
def book():

    # defining the api-endpoints
    PRICING_ENDPOINT = ...

    # data to be sent to api
    data = {...}

    # sending post request and saving response as response object
    try:
        r_pricing = requests.post(url = PRICING_ENDPOINT, data = data)
    except requests.exceptions.RequestException as e:
        return e
        sys.exit(1)

    # extracting response text
    POLL_ENDPOINT = r_pricing.headers['location']

    # setting data for poll
    data_for_poll = {...}

    r_poll = requests.get(POLL_ENDPOINT, data = data_for_poll)

    # poll loop, looking for 'UpdatesComplete'
    j = 1
    poll_json = r_poll.json()
    update_status = poll_json['Status']

    while update_status == 'UpdatesPending':
        time.sleep(2)
        j = float(j) + float(1)
        r_poll = requests.get(POLL_ENDPOINT, data = data_for_poll)
        poll_json = r_poll.json()
        update_status = poll_json['Status']

    return r_poll.text

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Возможно, вы получаете эту ошибку из-за истечения времени ожидания соединения HTTP с вашим сервером API, который зацикливается. Существуют некоторые стандарты для соединения по времени HTTP, и для цикла требуется больше времени, отведенного для соединения. Первое (прямое) решение - «поиграть» с конфигами Apache и увеличить время HTTP-соединения для вашего wsgi. Вы также можете установить сокетное соединение и в нем проверить состояние обновления и закрыть его, пока цель была достигнута. Или вы можете перенести свою логику на клиентскую сторону.

0 голосов
/ 11 января 2019

Это скорее архитектурная проблема, нежели проблема с колбой. Долгосрочные задачи в представлениях Flask всегда плохой выбор дизайна. В этом случае ответ маршрута зависит от двух конечных точек другого сервера. По сути, помимо ответственности за ваше приложение, вы несете ответственность и за другой сервер.

Поскольку дизайн приложения является прокси для другого сервиса, я бы порекомендовал создать прокси правильным образом. Так же, как book() предлагает прокси для PRICING_ENDPOINT POST-запроса, создайте другой маршрут для POLL_ENDPOINT GET-запроса и переместите логику опроса в код клиента (JS).

Обновление: Если по какой-то причине вы не можете доверять клиенту (браузер -> JS) информацию POLL_ENDPOINT в скрытой ситуации, подобной прокси, то, возможно, перенесите опрос в исполнитель задач, такой как Celery или Python RQ. Хотя это добавит дополнительные компоненты к вашему приложению, это будет верный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...