前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Django和FastCGI管理长时间运行的过程

使用Django和FastCGI管理长时间运行的过程

原创
作者头像
用户11021319
发布2024-03-29 09:54:53
1040
发布2024-03-29 09:54:53
  1. 问题背景:
    • 有一个Django+FastCGI的应用程序,需要修改以执行长时间的计算(可能长达半小时或更久)。
    • 需要在后台运行计算,并返回“您的作业已启动”类型的响应。
    • 在进程运行期间,进一步访问该URL应返回“您的作业仍在运行”,直到作业完成,此时应返回作业结果。
    • 以后任何对该URL的访问都应返回缓存的结果。
    • 对Django不太熟悉,不知道是否有内置的方法来实现想要的功能。
    • 尝试通过subprocess.Popen()启动进程,但除了在进程表中留下一个失效的条目之外,它工作正常。
    • 需要一个干净的解决方案,可以在进程完成后删除临时文件和进程的任何痕迹。
    • 也尝试了fork()和线程,但还没有想出可行的解决方案。
    • 想知道对于看似很常见的用例,是否存在规范的解决方案。
  2. 解决方案:
    • 可以使用两种可能的解决方案:
      • 调度长时任务到长时任务管理程序(可能是上面提到的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
复制
     ```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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档