Данные запроса кажутся грязными в многопоточном flask приложении - PullRequest
1 голос
/ 17 июня 2020

Мы наблюдаем случайную ошибку, которая, по всей видимости, вызвана перепутанием данных двух запросов. Мы получаем запрос на указание стоимости доставки на Order, но запрос не выполняется, потому что запрошенный Order недоступен для запрашивающей учетной записи. Я ищу тех, кто может дать представление о том, что здесь может происходить, я не нашел ничего в Google, официальных flask каналах помощи или ТАК, что похоже на то, что мы переживаем.

Мы развернуты на AWS, с apache, mod_wsgi, 1 процессом, 15 потоками, примерно 10 экземплярами.

Вот код, который отправляет электронное письмо:

    msg = f"Order ID {self.shipping.order.id} is not valid for this Account {self.user.account_id}"
    body = f"Error:<br/>{msg}<br/>Request Data:<br/>{request.data}<br/>Headers:<br/>{request.headers}"
    send_email(msg, body, "devops@*******.com")
    request_data = None

Проблема в том, что в этом сценарии мы отправляем себе по электронной почте сообщение об ошибке и данные запроса, а данные запроса, которые мы получаем, во многих случаях никогда бы не попали в этот конкретный фрагмент кода. Это может быть запрос от внешнего интерфейса, чтобы получить текущие настройки пользователя, например, которые не ссылаются на какие-либо заказы, не говоря уже о попытках получить для них стоимость доставки.

Сравнение журналов приложений с apache s access_log, мы видим, что во всех случаях мы получали два запроса на один и тот же экземпляр, один из которых запрашивал цитирование, а другой - запрос, который фактически регистрируется. Мы не знаем, обрабатываются ли эти два запроса одним и тем же потоком в быстрой последовательности или разными потоками, но они настолько близки друг к другу, что я думаю, что последнее гораздо более вероятно. У нас нет возможности однозначно связать записи access_log с журналом приложения, поэтому мы не знаем, какой из запросов регистрирует ошибку, но факт в том, что мы перенаправляемся к представлению, которое не соответствует содержанию запроса (т. е. мы не уверены, получает ли запрос цитирования неправильный объект запроса или другой направляется в неправильное представление).

Другой факт, который Интересно то, что мы используем graphql, поэтому часть маршрутизации выполняется после того, как flask / werkzeug выполняет их, но тело, которое мы получаем от flask.request в момент появления ошибки, не соответствует graphql выполняемая функция / мутация. Но это также происходит в представлениях, отображаемых напрямую через flask. Рабочий процесс flask-login ищет пользователя в самом начале, и он соответствует «плохому» запросу (т.е. тому, который не предназначен для цитирования).

1 Ответ

0 голосов
/ 10 июля 2020

Фактическая проблема заключалась в ошибке в одной из библиотек python-graphql (promise), а не в Flask, werkzeug или apache. Это были не данные запроса, которые «перемещались» в другой поток, а другой поток, пытающийся выполнить обещание для запроса, который должен был быть обработан в другом месте.

...