Django,sleep()暂停所有进程,但只有没有GET参数? [英] Django, sleep() pauses all processes, but only if no GET parameter?
问题描述
使用Django(由Webfaction托管),我有以下代码
Using Django (hosted by Webfaction), I have the following code
import time
def my_function(request):
time.sleep(10)
return HttpResponse("Done")
这是通过Django执行,当我去我的网址,www.mysite.com
This is executed via Django when I go to my url, www.mysite.com
我输入两次,立即彼此之间的url。我看到的方式,这两个都应该在10秒后完成。然而,第二个呼叫等待第一个呼叫,并在20秒后完成。
I enter the url twice, immediately after each other. The way I see it, both of these should finish after 10 seconds. However, the second call waits for the first one and finishes after 20 seconds.
然而,如果我输入一些虚拟GET参数,请访问www.mysite.com?dummy=1和www.mysite.com?dummy=2,然后他们都完成10秒。所以他们都可以同时运行。
If, however, I enter some dummy GET parameter, www.mysite.com?dummy=1 and www.mysite.com?dummy=2 then they both finish after 10 seconds. So it is possible for both of them to run simultaneously.
就像sleep()的范围在某种程度上是全局的?可能输入一个参数使它们以不同的进程运行而不是相同?
It's as though the scope of sleep() is somehow global?? Maybe entering a parameter makes them run as different processes instead of the same???
它由Webfaction托管。 httpd.conf有:
It is hosted by Webfaction. httpd.conf has:
KeepAlive Off
Listen 30961
MaxSpareThreads 3
MinSpareThreads 1
ServerLimit 1
SetEnvIf X-Forwarded-SSL on HTTPS=1
ThreadsPerChild 5
$ b $我确实需要使用sleep()并相信它不会阻止所有的事情。那么,怎么解决呢?
I do need to be able to use sleep() and trust that it isn't stopping everything. So, what's up and how to fix it?
编辑:Webfaction使用Apache运行。
Webfaction runs this using Apache.
推荐答案
如Gjordis指出,睡眠会暂停当前线程。我看过Webfaction,看起来他们正在使用WSGI来运行Django的服务实例。这意味着,每当一个请求进入时,Apache将会查看当前正在运行的工作进程(每个进程都是运行Django的一个实例)。如果没有/看到它会产生附加的工作人员并将请求交给他们。
As Gjordis pointed out, sleep will pause the current thread. I have looked at Webfaction and it looks like their are using WSGI for running the serving instance of Django. This means, every time a request comes in, Apache will look at how many worker processes (that are processes that each run a instance of Django) are currently running. If there are none/to view it will spawn additonally workers and hand the requests to them.
这是我认为发生的情况:
Here is what I think is happening in you situation:
- first GET请求资源A进来。Apache使用正在运行的工作人员(或启动新的工作人员)
- 工作人员在此期间睡眠10秒
- 对资源A的新请求进来,Apache看到它正在请求相同的资源,并将它发送给与请求A相同的工作人员。我猜这里的假设是最近处理特定资源的请求的工作人员更有可能该工作者有一些信息缓存/预处理/任何可以更快地处理此请求的
- 这将导致20秒的块,因为只有工作人员等待2次10秒
-
- first GET request for resource A comes in. Apache uses a running worker (or starts a new one)
- the worker sleeps 10 seconds
- during this, a new request for resource A comes in. Apache sees it is requesting the same resource and sends it to the same worker as for request A. I guess the assumption here is that a worker that recently processes a request for a specific resource it is more likely that the worker has some information cached/preprocessed/whatever so it can handle this request faster
- this results in a 20 second block since there is only on worker that waits 2 times 10 seconds
这个行为使99%的时间完全有意义,所以在逻辑上这样做是默认的。
This behavior makes completely sense 99% of the time so it's logically to do this on default.
但是,如果您更改第二个请求所请求的资源(通过添加GET参数),Apache将会假设这一点是一个不同的资源,并将启动另一个工作(因为第一个已经是忙(Apache不知道你没有做任何辛苦的工作)。既然现在有两个工人,两个等待10秒,总共下降到10秒。
此外,我假设您的设计有一些错误。几乎没有任何情况下,我可以想到,尽可能快地回应HTTP请求是合理的。毕竟,你想在最短的时间内尽可能多地提供请求,所以睡眠10秒是最适合你的事情。我会建议你创建一个新的问题,并说明你正在努力实现的实际目标。我很确定有一个更明智的解决方案!
However, if you change the requested resource for the second request (by adding GET parameter) Apache will assume that this is a different resource and will start another worker (since the first one is already "busy" (Apache can not know that you are not doing any hard work). Since there are now two worker, both waiting 10 seconds the total time goes down to 10 seconds.
Additionally I assume that something is wrong with your design. There are almost no cases which I can think of where it would be sensible to not respond to a HTTP request as fast as you can. After all, you want to serve as many requests as possible in the shortest amount of time, so sleeping 10 seconds is the most counterproductive thing you can do. I would recommend the you create a new question and state what you actual goal is that you are trying to achieve. I'm pretty sure there is a more sensible solution to this!
这篇关于Django,sleep()暂停所有进程,但只有没有GET参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!