我有一组资源,其表示被懒惰地创建.构建这些表示的计算可能需要几毫秒到几个小时,具体取决于服务器负载,特定资源和月亮的相位.
收到的第一个GET请求开始在服务器上进行计算.如果计算在几秒钟内完成,则返回计算的表示.否则,返回202"已接受"状态代码,客户端必须轮询资源,直到最终表示可用.
出现这种情况的原因如下:如果结果在几秒钟内可用,则需要尽快检索; 否则,当它变得可用时并不重要.
由于内存有限和请求量很大,NIO和长轮询都不是一个选项(即我无法保持足够的连接打开,甚至我甚至无法将所有请求都放在内存中;一次"几秒钟"已经过去了,我坚持多余的要求).同样,客户端限制使得它们无法处理完成回调.最后,请注意我对创建一个POST的"工厂"资源不感兴趣,因为额外的往返意味着我们的分段实时约束超出了预期(此外,它是额外的复杂性;此外,这是一种资源,受益于缓存).
我想在返回202"接受"状态代码以响应GET请求方面存在一些争议,因为我在实践中从未见过它,并且它最直观的用法是回应不安全的方法,但我从来没有发现任何特别令人沮丧的事情.而且,我不保持安全和幂等性吗?
那么,人们对这种方法有何看法?
编辑:我应该提到这是一个所谓的商业网络API - 不适用于浏览器.
我有一个通过apache/mod_wsgi托管的django实例.我使用pre_save和post_save信号存储保存前后的值,以便以后进行比较.为此,我使用全局变量来存储pre_save可以在post_save信号处理程序中访问的值.
我的问题是,如果两个请求A和B同时请求同一个Web服务,那么它是并发的吗?B不应读取由A写入的全局变量,反之亦然.
PS:我不对Lock变量使用任何线程.
我正在尝试使用gunicorn及其异步工作者提供长时间运行的请求,但我找不到任何可以开始工作的示例.我在这里使用了这个例子,但在返回响应之前调整了添加假延迟(睡眠5秒):
def app(environ, start_response):
data = "Hello, World!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
time.sleep(5)
return iter([data])
Run Code Online (Sandbox Code Playgroud)
然后我跑了gunicorn所以:
gunicorn -w 4 myapp:app -k gevent
当我打开两个浏览器选项卡并输入http://127.0.0.1:8000/它们并几乎同时发送请求时,请求似乎按顺序处理- 一个在5秒后返回,另一个在另外 5秒后返回.
问:我猜测睡眠不是友好的吗?但是有4个工人,所以即使工人的类型是"同步",两个工人应该同时处理两个请求?
apache ×1
asynchronous ×1
concurrency ×1
django ×1
gunicorn ×1
http-get ×1
mod-wsgi ×1
python ×1
worker ×1