-
问题背景:
- 有一个Django+FastCGI的应用程序,需要修改以执行长时间的计算(可能长达半小时或更久)。
- 需要在后台运行计算,并返回“您的作业已启动”类型的响应。
- 在进程运行期间,进一步访问该URL应返回“您的作业仍在运行”,直到作业完成,此时应返回作业结果。
- 以后任何对该URL的访问都应返回缓存的结果。
- 对Django不太熟悉,不知道是否有内置的方法来实现想要的功能。
- 尝试通过subprocess.Popen()启动进程,但除了在进程表中留下一个失效的条目之外,它工作正常。
- 需要一个干净的解决方案,可以在进程完成后删除临时文件和进程的任何痕迹。
- 也尝试了fork()和线程,但还没有想出可行的解决方案。
- 想知道对于看似很常见的用例,是否存在规范的解决方案。
-
解决方案:
-
可以使用两种可能的解决方案:
- 调度长时任务到长时任务管理程序(可能是上面提到的Django-Queue-Service)。
- 将结果永久保存,无论是文件还是数据库。
-
preferred to use temporary files and to remember their locaiton in the session data. It cannot be made more simple:
-
代码示例:
import sys from time import sleep
-
i = 0
while i < 1000:
print(‘myjob:’, i)
i = i+1
sleep(0.1)
sys.stdout.flush()
```python
from tempfile import mkstemp
from os import fdopen,unlink,kill
from subprocess import Popen
import signal
def startjob(request):
"""Start a new long running process unless already started."""
if not request.session.has_key('job'):
# create a temporary file to save the resuls
outfd,outname=mkstemp()
request.session['jobfile']=outname
outfile=fdopen(outfd,'a+')
proc=Popen("python myjob.py",shell=True,stdout=outfile)
# remember pid to terminate the job later
request.session['job']=proc.pid
return HttpResponse('A <a href="/showjob/">new job</a> has started.')
def showjob(request):
"""Show the last result of the running job."""
if not request.session.has_key('job'):
return HttpResponse('Not running a job.'+\
'<a href="/startjob/">Start a new one?</a>')
else:
filename=request.session['jobfile']
results=open(filename)
lines=results.readlines()
try:
return HttpResponse(lines[-1]+\
'<p><a href="/rmjob/">Terminate?</a>')
except:
return HttpResponse('No results yet.'+\
'<p><a href="/rmjob/">Terminate?</a>')
return response
def rmjob(request):
"""Terminate the runining job."""
if request.session.has_key('job'):
job=request.session['job']
filename=request.session['jobfile']
try:
kill(job,signal.SIGKILL) # unix only
unlink(filename)
except OSError, e:
pass # probably the job has finished already
del request.session['job']
del request.session['jobfile']
return HttpResponseRedirect('/startjob/') # start a new one
标签:return,request,Django,job,session,长时间,import,FastCGI
From: https://blog.csdn.net/huakej_/article/details/137134953