Closed (fixed)
Project:
Drush
Component:
Base system (internal API)
Priority:
Normal
Category:
Feature request
Assigned:
Reporter:
Created:
9 Feb 2012 at 00:53 UTC
Updated:
3 Apr 2012 at 13:40 UTC
Jump to comment: Most recent file
We'll have a little work to do in our queue to accommodate. See: #1433406: Make hosting (specifically hosting-dispatch) work with Drush 5
| Comment | File | Size | Author |
|---|---|---|---|
| #32 | drush-invoke-process-fork-32.patch | 3.04 KB | greg.1.anderson |
| #31 | drush-invoke-process-fork-1433556-31.patch | 4.37 KB | alexpott |
| #25 | drush-invoke-process-fork-1433556-25.patch | 4.32 KB | alexpott |
| #22 | drush-invoke-process-fork-1433556-22.patch | 3.57 KB | alexpott |
| #21 | drush-invoke-process-fork-1433556-21.patch | 3.56 KB | alexpott |
Comments
Comment #1
greg.1.anderson commentedHere's a first attempt, completely untested.
Comment #2
tstoecklerNow getting fatal: Undefined function drush_backend_invoke_args()It should be possible to replace that with drush_invoke_process(), too, though, right?
EDIT: Sorry, wrong issue.
Comment #3
tstoecklerHmm.. this isn't working for me.
I also tried bringing the exact Drush 4 behavior back á la:
(Just like in http://api.drush.org/api/function/drush_backend_fork/4.x)
but that didn't work either.
That said, is there any more reliabe way to test this? Currently I'm just using Aegir with the patch over at #1433406: Make hosting (specifically hosting-dispatch) work with Drush 5, but, as before, what happens is that the tests run through, but the Task isn't marked as comleted, i.e. the spinner keeps spinning. That's probably not the most reliable way to test this, though.
Comment #4
greg.1.anderson commentedIt does not appear to be possible to run Drush in the background. To whit:
Contrast with:
Most shell commands, when run in the background, behave like the second example. They run, they complete, they print "Done". Something that drush is doing causes it to stop. It's not in the bash wrapper;
/usr/bin/php /home/ga/local/drush/drush.php --php=/usr/bin/php version --debug &also stops prior to producing any output. I presume this is related to:This would be perfectly understandable if Drush was being called with --backend, but I don't think that Drush reads from stdin unless --backend is specified.
However, it also appears that Drush-4.x behaves the same way. Does Aegir work on the HEAD of Drush-4.x with drush_backend_fork? I presume that it does; perhaps there is something wrong with my experiments, then? No time to trace this farther right now.
Comment #5
alexpottThe patch in #1 works fine for me running following code using the command "drush scr fork5.php". With the patch we get 10 simultaneous processes as expected.
I've tested this on both Centos 5.2 and Mac OS X Lion... it works as expected on both OSes. Interesting on Centos:
On MacOS X it exhibits the behaviour Greg described above - stopping until the command fg is used.
Comment #6
alexpott... and I can confirm that #1437762: Backend drush command reparsed by escapeshellcmd() which causes issues if you're using a drush.ini file is fixed in drush5
Comment #7
greg.1.anderson commentedSetting status until we can figure out what is going on with the blocking behavior.
Comment #8
alexpottHi Greg,
This is not an issue for drush but occurs for all php commands run from the command line.
If you create a php script test.php as
Try running php test.php & it hangs too on Mac OS X
Run it using thisphp test.php < /dev/null & and it does not
Same for drush version < /dev/null &
Comment #9
alexpottAfaik there is one outstanding issue for the patch in #1. When running the test described in #5 under drush5 lots of output is written to stdout which is not the case with drush4.
Is this a desired effect of the changes to backend.inc in drush5?
Comment #10
alexpottThis patch only prints backend output for forked processes if the verbose or debug options are set.
I think this patch is good to go.
Comment #11
tstoeckler@alexpott: Is there a specific way to test your patch?
Also, I cannot reproduce #8. It hangs for me either way...
Comment #12
greg.1.anderson commentedThe 'exit' in drush_backend_output is disquieting. Could this be done another way? At the very least it needs more explanation.
I tried #8, and it worked for me exactly as described. I'm on Ubuntu Linux. @tstoeckler: what platform did you test?
There does not seem to be any /dev/null input redirection in #10.
Comment #13
tstoecklerI'm on Debian 6.
I tried #8 again, and it works for me if you redirect the output to /dev/null. Redirecting the input doesn't work. Hmm..
Comment #14
greg.1.anderson commentedUsing a test.php that just prints one line (with a newline), this is what I am seeing:
The php program prints "wow" above. Then I must press [Enter] to see the done message:
As you can see, redirecting output does not prevent php from hanging in my tests. I don't have a Debian 6 install handy, but I have no theories about why your results should be different.
Oh, we could also use a backend fork unit test for #10.
Comment #15
alexpottGreg #12 - how right you are that was meant to be a return not an exit.
Anyhow I think the patch attached is a "cleaner" solution using a helper function - drush_backend_check_output() - to determine if the backend process should print to stdout.
Working some tests...
Comment #16
greg.1.anderson commentedIs it unnecessary to redirect input from /dev/null if all output is suppressed? Code is looking better, but still needs a unit test.
Comment #17
tstoecklerAhh, I didn't know that was the wanted behavior. (I told you I was a noob :)...)
Yes, I can reproduce exactly what you describe.
Comment #18
alexpottPatch now with added test goodness...
The test invokes a forked process that creates a file after a second in PHPUnit's sandbox folder. Meanwhile the test checks for the existence of this file then waits for 2 seconds and checks again.
Comment #20
greg.1.anderson commentedLooks good, but can we write the test file to UNISH_TMP instead of cwd?
Comment #21
alexpottNo problem... didn't know about UNISH_TMP :)
Comment #22
alexpottChanged to use UNISH_SANDBOX as that seems more consistent will other tests that are creating files eg. testArchiveDump
Comment #23
alexpottUpdating issue status...
Comment #24
moshe weitzman commentedWe need to document the 'fork' backend option. I'd like to state why one would use it, in addition to stating what it does.
Comment #25
alexpottGood point. Patch now includes documentation...
Comment #26
moshe weitzman commentedHow does fork help with 'Can be used to write commands that restart themselves before they run out of memory.'. We already do that with regular backend calls. See updatedb and migrate-import in migrate module. Furthermore, please state what happens with integrating results from forked calls. Return values are ignored?
Comment #27
moshe weitzman commentedCNW for docs
Comment #28
tstoecklerI tried to get this to work, but am getting a weird error:
When I verify a site, it re-saves the corresponding alias with the wrong path to the site. Namely it always uses the main hostmaster platform as a site path (i.e. /var/aegir/hostmaster-1.6/sites/foo instead of /var/aegir/platforms/bar/sites/foo).
So my question regarding drush_invoke_process is about the provision-save command. It takes an alias as an argument, so I don't know what to put in the $alias argument for drush_invoke_process.
I currently use '@self', because I thought it shouldn't really matter, but that does not seem to work. It may, of course, very well be, that my problem is caused by something else, but I thought I'd ask.
Comment #29
greg.1.anderson commented'@self' means the bootstrapped site. '@none' means no site. array('root' => '/path/to/drupal', 'uri' => 'mydrupalsite.org') to specify some other site. I'm not familiar with hostmaster, but if provision-save is taking an alias as the first parameter, maybe '@none' is what you want here. You should probably put hostmatster support requests in separate issues in the hostmaster queue, though.
Comment #30
tstoecklerThanks, I'll try that.
Yes, I first wanted to post this issue in the Hostmaster queue, but since this is specific to the Drush 5 port...
I'll still try to get this to work in the next few days, but for what its worth, the tasks now actually complete fully, so it seems the 'forking' part seems to work.
/me shuts up now to let the big guys fix this :)
Comment #31
alexpottPatch attached for another go at documentation. My primary use case for this functionality is http://drupal.org/project/drushd. This needs to be able to fork a process in a non-blocking way to allow daemon threads to refork safely.
The new documentation from the patch:
Comment #32
greg.1.anderson commentedI know I passed this in #20, but I've been looking at the backend code a lot today, and therefore have more opinions. :p Could we get rid of the --backend-fork option? --backend is not even used with the 'fork' option, so this seems unnecessary. I added --quiet for good measure, to reinforce the concept that you don't get the output in fork mode anyway. This does not stop the log messages from printing, but that does not affect the tests, so I think it is okay. Patch attached.
Comment #33
greg.1.anderson commentedI decided to provide a patch, but forgot to set status back to 'needs review'.
Comment #34
moshe weitzman commentedLooks fine. Perhaps use http://php.net/manual/en/function.usleep.php in order to wait less.
Comment #35
greg.1.anderson commentedCommitted with reduced sleep time. A milisecond in the subprocess was long enough to insure that the file did not exist to begin with; I did not feel inclined to tune it down any lower than that. I got failures with sleep times around a quarter of a second before checking to see if the file had been created, but it always worked at half a second. I did not try to tune it any closer than that, as we may get false failures on slow systems, or during load spikes. I suppose it would be better to sleep-and-check and sleep-and-check, and succeed when it shows up, or fail after some longer delay (a second or two), but didn't feel like being that involved with it.
Comment #36
greg.1.anderson commentedSet status.
Comment #37
greg.1.anderson commentedI went back and added the 'for' loop per #35 so that the test does not need to wait longer than necessary.