For the TimedMediaHandler I was adding more fine grain control over background processes [1] and ran into a unix issue around getting both a pid and exit status for a given background shell command.
Essentially with a background task I can get the pid or the exit status but can't seem to get both:
to get the pid: $pid = wfShellExec("nohup nice -n 19 $cmd > /tmp/stdout.log & echo $!";
put the exit status into a file: $pid = wfShellExec("nohup nice -n 19 $cmd > /tmp/stdout.log && echo $? > /tmp/exit.status";
But if I try to get both either my exit status is for the "echo pid" command or my pid is for the "echo exit status" command. It seems like there should be some shell trick back-reference background tasks or something
If nothing else I think this could be done with a shell script and pass in a lot of path targets and use the "wait $pid" command at the end to grab the exit code of the background process. Did a quick guess at what this would look like in that same commit[1], but would rather just do some command line magic instead of putting a .sh script in the extension.
[1] http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90068
peace, --michael
Michael Dale wrote:
For the TimedMediaHandler I was adding more fine grain control over background processes [1] and ran into a unix issue around getting both a pid and exit status for a given background shell command.
Essentially with a background task I can get the pid or the exit status but can't seem to get both:
Do you want the command to be run asynchronously or not? If you expect the status code to be returned by wfShellExec(), then the process will obviously have finished and there's no need for the PID. OTOH if you launch it as a background task, you will want to get the PID, and then call pcntl_waitpid* on it to get the status code.
*pcntl_waitpid() may not work, because $cmd is unlikely to be a direct children of php. You could also be expecting to check it from a different request. So you would enter into the world of killing -0 the process to check if it's still alive.
On 06/14/2011 05:41 PM, Platonides wrote:
Do you want the command to be run asynchronously or not? If you expect the status code to be returned by wfShellExec(), then the process will obviously have finished and there's no need for the PID. OTOH if you launch it as a background task, you will want to get the PID, and then call pcntl_waitpid* on it to get the status code.
*pcntl_waitpid() may not work, because $cmd is unlikely to be a direct children of php. You could also be expecting to check it from a different request. So you would enter into the world of killing -0 the process to check if it's still alive.
Yes the idea is to run the command asynchronously so we can monitor the transcode progress and kill it if it stops making progress.
Calling pcntl_waitpid with pcntl_fork as Tim mentions may be the way to get it done. With the child including the pcntl_waitpid call and the parent monitoring "progress" and killing the child if need be.
--michael
On 15/06/11 04:27, Michael Dale wrote:
For the TimedMediaHandler I was adding more fine grain control over background processes [1] and ran into a unix issue around getting both a pid and exit status for a given background shell command.
Essentially with a background task I can get the pid or the exit status but can't seem to get both:
to get the pid: $pid = wfShellExec("nohup nice -n 19 $cmd > /tmp/stdout.log & echo $!";
put the exit status into a file: $pid = wfShellExec("nohup nice -n 19 $cmd > /tmp/stdout.log && echo $? > /tmp/exit.status";
But if I try to get both either my exit status is for the "echo pid" command or my pid is for the "echo exit status" command. It seems like there should be some shell trick back-reference background tasks or something
Maybe something like:
#!/bin/bash trap 'kill %1' SIGINT SIGTERM
( $cmd > /tmp/stdout.log echo $? > /tmp/exit.status ) &
subshell="$!" cmdpid=
# Wait for the command to start for i in `seq 100`;do cmdpid=`ps --ppid "$subshell" -o pid --no-headers` if [ -n "$cmdpid" ]; then break fi sleep 0.1 done
# Return the PID to MediaWiki echo "$cmdpid"
There comes a point with every shell script project where you realise it would have been easier to use a real programming language from the start. In this case, doing it in PHP with pcntl_fork(), pcntl_exec() and pcntl_wait() would be a reasonable solution. In my experience, you can't ask the question "how do I do X in shell script" and expect to like the answer.
-- Tim Starling
On 15/06/11 01:18, Tim Starling wrote:
There comes a point with every shell script project where you realise it would have been easier to use a real programming language from the start. In this case, doing it in PHP with pcntl_fork(), pcntl_exec() and pcntl_wait() would be a reasonable solution. In my experience, you can't ask the question "how do I do X in shell script" and expect to like the answer.
That is why I had to start learning perl. It is a great shell language!
wikitech-l@lists.wikimedia.org