[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 197
  • Last Modified:

Spawning long process

I have built a cgi interface to a report generator. The reports take hours to generate, so I want to launch the task and return. I build a shell script that I then launch (for various reasons, it needs to be a shell script), but I cannot get it to return my "launched" message to the browser until the process is ended. How can I do this?
It would be sufficient to print the launched info, and then hang, but it won't print anything for me.
(FYI, my code is actually in Python, but I am hoping that the solution will be similar)
0
emmons
Asked:
emmons
  • 3
  • 2
1 Solution
 
alamoCommented:
I suspect there are two things happening here.

First is that any status messages you print before launching your script are probably being buffered and thus aren't sent to the browser. The solution is to turn buffering off, which is done in perl with "$| = 1;" (assuming STDOUT is the active filehandle). This will cause what you print to be sent back to the browser immediately.

Second, normally a shell script invoked via system() won't return until it completes. So if you are trying to print a "Launched successfully" message after your system() call it won't be printed until the process is done. The solution here is to launch your script as a background process, i.e. add "&" to the end of the command.

Good luck, hope this helps... if this turns out to be applicable to your problem I'll post it as an answer.
0
 
emmonsAuthor Commented:
thanks alamo.

I will try the buffering thing. Though I do a flush() and then a close() of stdin and stdout before I call my script.

I did try putting the ampersand after my task, but that runs it in the background and does not actually detach it from the shell. I fear that I need to run it as a detached process in order to get it to return.

In case it helps, the relevent code is...

def tellStatus( stuff) :
   printPageHeader()
   print stuff,
   print "<br>File ",
   print temp_file_name,
   print " has been submitted for execution<br>",
   print "please reference this number to the administrator<br>"
   sys.stdout.flush()
   sys.stdout.close()
   sys.stdin.close()

   tellStatus( "Close before fork")
   if( fork() == 0) :
# execute the code in a child process
      createScriptFile()
      chmod( temp_file_name, 0777)
      command_line = "nohup " + temp_file_name + " &"
      os.system( command_line)
      sys.exit(0)
   else :
      sys.exit(0)

0
 
alamoCommented:
Ok, the flush is making sure the messages are written by your program but the server isn't sending them to the client. The way around this is to tell the server to send everything you write directly to the client, by renaming your process so it starts with "nph", which stands wfor "non-parsed headers". This also means you will need to write all headers, so before your "Content-Type" line add:

print "HTTP/1.1 200 OK\n";

You can forget my suggestion with the "&", since it seems that's not the problem. Good luck!
0
 
alamoCommented:
Let me clarify that what you should rename to nphxxx is the script called by the server, not the shell script you are invoking.
0
 
emmonsAuthor Commented:
Is that how to get this stuff to be unbuffered??!!
Thank you very much. That should do it.

0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now