简体   繁体   English

在django视图中执行阻止请求

[英]Performing a blocking request in django view

In one of the views in my django application, I need to perform a relatively lengthy network IO operation. 在我的django应用程序的一个视图中,我需要执行相对冗长的网络IO操作。 The problem is other requests must wait for this request to be completed even though they have nothing to do with it. 问题是其他请求必须等待此请求完成,即使它们与它无关。 I did some research and stumbled upon Celery but as I understand, it is used to perform background tasks independent of the request. 我做了一些研究并偶然发现了Celery,但据我了解,它用于执行独立于请求的后台任务。 (so I can not use the result of the task for the response to the request) (所以我不能使用任务的结果来响应请求)

Is there a way to process views asynchronously in django so while the network request is pending other requests can be processed? 有没有办法在django中异步处理视图,所以当网络请求挂起时,可以处理其他请求?

Edit: What I forgot to mention is that my application is a web service using django rest framework. 编辑:我忘了提到的是我的应用程序是使用django rest框架的Web服务。 So the result of a view is a json response not a page that I can later modify using AJAX. 所以视图的结果是json响应,而不是我以后可以使用AJAX修改的页面。

The usual solution here is to offload the task to celery, and return a "please wait" response in your view. 这里通常的解决方案是将任务卸载到芹菜,并在您的视图中返回“请稍候”响应。 If you want, you can then use an Ajax call to periodically hit a view that will report whether the response is ready, and redirect when it is. 如果需要,您可以使用Ajax调用定期命中一个视图,该视图将报告响应是否准备就绪,并在何时重定向。

You want to maintain that HTTP connection for an extended period of time but still allow other requests to be managed, right? 您希望在较长时间内维持该HTTP连接,但仍允许管理其他请求,对吗? There's no simple solution to this problem. 这个问题没有简单的解决方案。 Also, any solution will be a level away from Django as it depends on how you process requests. 此外,任何解决方案都将远离Django,因为它取决于您处理请求的方式。

I don't know what you're currently using, so I can only tell you how I handled this in the past... I was using uwsgi to provide the WSGI interface between my python application and nginx. 我不知道你目前使用的是什么,所以我只能告诉你我过去是如何处理的......我正在使用uwsgi来提供我的python应用程序和nginx之间的WSGI接口。 In uwsgi I used the asynchronous functions to suspend my long running connection when there was time to wait on the IO connections. 在uwsgi中,当有时间等待IO连接时,我使用异步函数暂停长时间运行的连接。 The methods allow you to ask it to suspend things until there is something to read or write and then allow other connections to be serviced. 这些方法允许您要求它暂停,直到有东西要读或写,然后允许其他连接被服务。

The above mentioned async calls use "green threads". 上述异步调用使用“绿色线程”。 It's much lighter weight then regular threads and you have control over when you move from thread to thread. 它比普通线程轻得多,你可以控制从线程移动到线程的时间。

I am not saying that it is a good solution for your scenario[1], but the simple answer is using the following pattern: 我并不是说它对你的场景是一个很好的解决方案[1],但简单的答案是使用以下模式:

async_result = some_task.delay(arg1)
result = async_result.get()

Check documentation for the get method . 检查get方法的文档。 And instead of using the delay method you can use anything that returns an AsyncResult (like the apply_async method 而不是使用delay方法,您可以使用任何返回AsyncResult的东西(如apply_async方法


[1] Why it may be a bad idea? [1]为什么这可能是一个坏主意? Having an ongoing connection waiting a lot is bad for Django (it is not ready for long-lived connections), may conflict with the proxy configuration (if there is a reverse proxy somewhere) and may be identified as a timeout from the browser. 持续等待很多连接对Django来说是不好的(它还没有为长期连接做好准备),可能与代理配置冲突(如果某处存在反向代理),并且可能被识别为来自浏览器的超时。 So... it seems a Bad Idea[TM] to use this pattern for a Django Rest Framework view. 所以...在Django Rest Framework视图中使用此模式似乎是一个坏主意[TM]。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM