Merge lp:~jml/launchpad/sftp-poppy into lp:launchpad
| Status: | Merged |
|---|---|
| Approved by: | Jonathan Lange on 2010-03-18 |
| Approved revision: | no longer in the source branch. |
| Merged at revision: | not available |
| Proposed branch: | lp:~jml/launchpad/sftp-poppy |
| Merge into: | lp:launchpad |
| Diff against target: |
485 lines (+125/-146) 8 files modified
lib/canonical/launchpad/daemons/tachandler.py (+83/-47) lib/lp/poppy/filesystem.py (+0/-1) lib/lp/poppy/tests/__init__.py (+5/-0) lib/lp/poppy/tests/helpers.py (+8/-16) lib/lp/poppy/tests/test_poppy.py (+17/-23) lib/lp/services/osutils.py (+8/-54) lib/lp/soyuz/doc/soyuz-upload.txt.disabled (+1/-1) lib/lp/testing/__init__.py (+3/-4) |
| To merge this branch: | bzr merge lp:~jml/launchpad/sftp-poppy |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Gavin Panella (community) | Approve on 2010-03-18 | ||
| Michael Nelson | 2010-03-18 | Pending | |
|
Review via email:
|
|||
Commit Message
Add two_stage_kill, speed up tachandler and kill by pidfile. Clean up poppy tests.
Description of the Change
Contrary to what you might expect, this branch actually has nothing to do with SFTP. Instead, it does a bunch of cleanups and fixes to testing code that I had to touch in order to start thinking about with Poppy.
canonical/
Use osutils.
lp/services/
Extract the two-stage kill part of osutils.
Fix a bug in the two-stage kill algorithm. If you terminate a process and don't give it the chance to report its results back to the parent process, the terminated process remains as a zombie. Without the waitpid, the polling loop will *always* run to completion and then do the SIGKILL, thus making the call take over 5s guaranteed.
Fixing this may well make some layers tear down faster.
lp/poppy/
Remove flakes.
lp/poppy/
lp/poppy/
Move all of the helper code out of __init__ and into helpers.py. Add a stub __init__.py.
Fix up some of the formatting in helpers, and re-use two_stage_kill, getting rid of the slow (wait for 2s) two-stage kill implementation here.
lp/poppy/
Bits and pieces of cleanup:
* Use lp.testing.TestCase
* Fix some flakes
* Rename tests to test_foo from testFoo, according to the standard
* Delete the useless layer
* Fix spelling mistakes
* Use addCleanup instead of tearDown
* Use makeTemporaryDi
* Whitespace cleanups
lp/soyuz/
The return value of killPoppy isn't useful and isn't used.
lp/testing/
Avoid using lambdas in addCleanup -- this is a throwback to an old addCleanup API. Re-use makeTemporaryDi
Thanks,
jml
| Michael Nelson (michael.nelson) wrote : | # |
Review: Approve
Nothing I can add to Gavin's (which you're investigating).
On Thu, Mar 18, 2010 at 11:35 AM, Jonathan Lange <email address hidden> wrote:
> Jonathan Lange has proposed merging lp:~jml/launchpad/sftp-poppy into lp:launchpad/devel.
>
> Requested reviews:
> Canonical Launchpad Engineering (launchpad)
>
>
> Contrary to what you might expect, this branch actually has nothing to do with SFTP. Instead, it does a bunch of cleanups and fixes to testing code that I had to touch in order to start thinking about with Poppy.
>
> canonical/
>
> Use osutils.
>
> lp/services/
>
> Extract the two-stage kill part of osutils.
>
> Fix a bug in the two-stage kill algorithm. If you terminate a process and don't give it the chance to report its results back to the parent process, the terminated process remains as a zombie. Without the waitpid, the polling loop will *always* run to completion and then do the SIGKILL, thus making the call take over 5s guaranteed.
Nice.
>
> Fixing this may well make some layers tear down faster.
>
> lp/poppy/
>
> Remove flakes.
>
> lp/poppy/
> lp/poppy/
>
> Move all of the helper code out of __init__ and into helpers.py. Add a stub __init__.py.
>
> Fix up some of the formatting in helpers, and re-use two_stage_kill, getting rid of the slow (wait for 2s) two-stage kill implementation here.
>
> lp/poppy/
>
> Bits and pieces of cleanup:
> * Use lp.testing.TestCase
> * Fix some flakes
> * Rename tests to test_foo from testFoo, according to the standard
> * Delete the useless layer
> * Fix spelling mistakes
> * Use addCleanup instead of tearDown
> * Use makeTemporaryDi
> * Whitespace cleanups
>
> lp/soyuz/
>
> The return value of killPoppy isn't useful and isn't used.
>
> lp/testing/
>
> Avoid using lambdas in addCleanup -- this is a throwback to an old addCleanup API. Re-use makeTemporaryDi
>
> Thanks,
> jml
> --
> https:/
> Your team Launchpad code reviewers from Canonical is subscribed to branch lp:launchpad/devel.
>
> === modified file 'lib/canonical/
> --- lib/canonical/
> +++ lib/canonical/
> @@ -16,12 +16,12 @@
> import sys
> import os
> import time
> -from signal import SIGTERM, SIGKILL
> import subprocess
>
> from twisted.application import service
> from twisted.python import log
>
> +from lp.services.osutils import kill_by_pidfile
>
> twistd_script = os.path.
> os.path.
> @@ -118,39 +11...
| Jonathan Lange (jml) wrote : | # |
On Thu, Mar 18, 2010 at 11:57 AM, Gavin Panella
<email address hidden> wrote:
> Review: Approve
> Looks good. Two comments:
>
> * It's not necessary to do waitpid(pid, os.WNOHANG) followed by
> kill(pid, 0); the return value from waitpid() will be (0, 0) when
> the process has not exited yet, and it will error the same as kill()
> if the process does not exist.
>
Hmm. I see. I wasn't quite sure what the behaviour actually is, so I
did Science.
$ ps ax | grep 3711
7702 pts/2 R+ 0:00 grep 3711
$ python
Python 2.6.4 (r264:75706, Dec 7 2009, 18:43:55)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
Spawn a long-running process
>>> pid = os.spawnv(
>>> pid
7820
waitpid on-existent process raises errors
>>> os.waitpid(3711, os.WNOHANG)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 10] No child processes
waitpid returns (0, 0) while it's running for (pid, result)
>>> os.waitpid(7820, os.WNOHANG)
(0, 0)
Once it's terminated, returns (pid, result) with a non-zero pid.
>>> os.waitpid(7820, os.WNOHANG)
(7820, 0)
Now that it's terminated and we've reaped it, it'll raise an exception
>>> os.waitpid(7820, os.WNOHANG)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 10] No child processes
I'll fix the code accordingly, making sure that we don't force a 0.1s
sleep if the SIGTERM was successful.
> * It might be nice to be able to pass a subprocess.Popen into
> two_stage_kill, so that its poll() method is used, and so the
> returncode attribute is set correctly to avoid confusion. But,
> really, this is probably not worth the effort.
It's valuable having a low-level function that takes a pid. I agree
that what you describe would also be useful, but maybe not right now.
I wonder what we have to do to encourage others who might need this to
stick code into this module and re-use two-stage kill.
Thanks!
jml
| Gavin Panella (allenap) wrote : | # |
jml wrote:
> I wonder what we have to do to encourage others who might need this to
> stick code into this module and re-use two-stage kill.
Get it into the standard library! :)

Looks good. Two comments:
* It's not necessary to do waitpid(pid, os.WNOHANG) followed by
kill(pid, 0); the return value from waitpid() will be (0, 0) when
the process has not exited yet, and it will error the same as kill()
if the process does not exist.
* It might be nice to be able to pass a subprocess.Popen into
two_stage_kill, so that its poll() method is used, and so the
returncode attribute is set correctly to avoid confusion. But,
really, this is probably not worth the effort.