Start background process/daemon from CGI script

后端 未结 10 1083
北恋
北恋 2020-12-10 02:02

I\'m trying to launch a background process from a CGI scripts. Basically, when a form is submitted the CGI script will indicate to the user that his or her request is being

相关标签:
10条回答
  • 2020-12-10 02:58

    Ok, I'm adding a simpler solution, if you don't need to start another script but continue in the same one to do the long process in background. This will let you give a waiting message instantly seen by the client and continue your server processing even if the client kill the browser session:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import os
    import sys
    import time
    import datetime
    
    print "Content-Type: text/html;charset=ISO-8859-1\n\n"
    print "<html>Please wait...<html>\n"
    sys.stdout.flush()
    os.close(sys.stdout.fileno()) # Break web pipe
    if os.fork(): # Get out parent process
       sys.exit()
    
    # Continue with new child process
    time.sleep(1)  # Be sure the parent process reach exit command.
    os.setsid() # Become process group leader
    
    # From here I cannot print to Webserver.
    # But I can write in other files or do any long process.
    f=open('long_process.log', 'a+')
    f.write( "Starting {0} ...\n".format(datetime.datetime.now()) )
    f.flush()
    time.sleep(15)
    f.write( "Still working {0} ...\n".format(datetime.datetime.now()) )
    f.flush()
    time.sleep(300)
    f.write( "Still alive - Apache didn't scalped me!\n" )
    f.flush()
    time.sleep(150)
    f.write( "Finishing {0} ...\n".format(datetime.datetime.now()) )
    f.flush()
    f.close()
    

    I have read half the Internet for one week without success on this one, finally I tried to test if there is a difference between sys.stdout.close() and os.close(sys.stdout.fileno()) and there is an huge one: The first didn't do anything while the second closed the pipe from the web server and completly disconnected from the client. The fork is only necessary because the webserver will kill its processes after a while and your long process probably needs more time to complete.

    0 讨论(0)
  • 2020-12-10 02:59

    As other answers have noted, it is tricky to start a persistent process from your CGI script because the process must cleanly dissociate itself from the CGI program. I have found that a great general-purpose program for this is daemon. It takes care of the messy details involving open file handles, process groups, root directory, etc etc for you. So the pattern of such a CGI program is:

    #!/bin/sh
    foo-service-ping || daemon --restart foo-service
    
    # ... followed below by some CGI handler that uses the "foo" service
    

    The original post describes the case where you want your CGI program to return quickly, while spawning off a background process to finish handling that one request. But there is also the case where your web application depends on a running service which must be kept alive. (Other people have talked about using beanstalkd to handle jobs. But how do you ensure that beanstalkd itself is alive?) One way to do this is to restart the service (if it's down) from within the CGI script. This approach makes sense in an environment where you have limited control over the server and can't rely on things like cron or an init.d mechanism.

    0 讨论(0)
  • 2020-12-10 02:59

    I haven't tried using fork but I have accomplished what you're asking by executing a sys.stdout.flush() after the original message, before calling the background process.

    i.e.

    print "Please wait..."
    sys.stdout.flush()
    
    output = some_processing() # put what you want to accomplish here
    print output               # in my case output was a redirect to a results page
    
    0 讨论(0)
  • 2020-12-10 03:00

    I wouldn't suggets going about the problem this way. If you need to execute some task asynchronously, why not use a work queue like beanstalkd instead of trying to fork off the tasks from the request? There are client libraries for beanstalkd available for python.

    0 讨论(0)
提交回复
热议问题