python - 将 flask.request 传递给另一个线程
问题描述
我对是否可以将 Flask 的request
对象发送到另一个线程进行处理感到有点困惑。我正在尝试使用在 Elasticsearch 中存储与请求相关的数据after_request
。为了尽快处理请求,我试图将处理卸载到单独的线程:
from datetime import datetime
import socket
from threading import Thread
from elasticsearch import Elasticsearch
from flask import current_app, request
def after_request(response):
Thread(
target=_process_data, args=(
current_app._get_current_object(),
request._get_current_object()
)
).start()
return response
def _process_data(app, request):
data = {
'timestamp': datetime.utcnow(),
'scheme': request.environ.get('REQUEST_SCHEME'),
'protocol': request.environ.get('SERVER_PROTOCOL'),
'method': request.environ.get('REQUEST_METHOD'),
'uri': request.environ.get('REQUEST_URI'),
'remote_addr': request.environ.get('REMOTE_ADDR'),
'remote_port': int(request.environ.get('REMOTE_PORT')),
'server_name': request.environ.get('SERVER_NAME'),
'server_port': int(request.environ.get('SERVER_PORT')),
'app_server': socket.gethostname(),
'request_headers': dict(request.headers)
}
elastic = Elasticsearch('localhost:9200')
elastic.index(index=app.config['TRACKING_ES_INDEX'], doc_type='_doc', body=data)
但是,我开始在 Elasticsearch 中看到的是带有空request_headers
字段 ( {}
) 的文档,尤其是在对应用程序进行负载测试时。当我尝试将data
字典填充到after_request
并传递data
到时_process_data
,一切都按预期工作。
该文档指出:
上下文对于每个线程(或其他工作类型)都是唯一的。请求不能传递给另一个线程,另一个线程将有不同的上下文堆栈,并且不会知道父线程指向的请求。
但是,在几段之后,它指出:
在某些情况下需要对代理对象的引用,例如发送信号或将数据传递给后台线程。
所以我假设使用request._get_current_object()
来获取实际对象并将其传递给分离的线程会起作用。但显然,我错过了一些东西......
解决方案
推荐阅读
- sql - SQL SERVER 2016 慢插入
- c - 不知道为什么我不能在第 112 行打印成本。它说
- python - 为什么在我告诉它 POST 之后请求使用 GET?
- kotlin - 如何使用 HttpRequest.sendStream() 获取上传文件的状态?
- javascript - 使用带有可变根元素的解析 JSON 的 JavaScript 对象
- netsuite - Netsuite 项目搜索 - 目标:显示可用数量非零的项目
- c# - 字符串根据条件拆分
- selenium - VSTS (Azure DevOps) 中的 Selenium 屏幕截图
- r - 将散点与跨越小提琴图填充条件的线配对
- hibernate - 何时/如何以编程方式设置 Hibernate 使用的 Ehcache 大小