Make sure our command line calls always exit
sarge's "wait_events" is unreliable. If an asynchronous job is started but stops immediately and raises a sarge Exception (inside the async thread), the associated command's event will never be set event though the process finished. So we'd wait indefinitely here. We circumvent this by first waiting until the commands are parsed and processed (p.commands contains elements), then until said commands are started and then making sure the command's process is actually set. Only then do we actually have a background process running that we'll be able to monitor further down, otherwise the command immediately failed.
This commit is contained in:
parent
528e99898f
commit
a66e6b603f
1 changed files with 16 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ __copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms
|
|||
import sarge
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
|
||||
from . import to_unicode
|
||||
|
||||
|
|
@ -80,7 +81,21 @@ class CommandlineCaller(object):
|
|||
kwargs.update(dict(async=True, stdout=sarge.Capture(), stderr=sarge.Capture()))
|
||||
|
||||
p = sarge.run(command, **kwargs)
|
||||
p.wait_events()
|
||||
while len(p.commands) == 0:
|
||||
# somewhat ugly... we can't use wait_events because
|
||||
# the events might not be all set if an exception
|
||||
# by sarge is triggered within the async process
|
||||
# thread
|
||||
time.sleep(0.01)
|
||||
|
||||
# by now we should have a command, let's wait for its
|
||||
# process to have been prepared
|
||||
p.commands[0].process_ready.wait()
|
||||
|
||||
if not p.commands[0].process:
|
||||
# the process might have been set to None in case of any exception
|
||||
self._logger.error(u"Error while trying to run command {}".format(joined_command))
|
||||
return None, [], []
|
||||
|
||||
all_stdout = []
|
||||
all_stderr = []
|
||||
|
|
|
|||
Loading…
Reference in a new issue