summaryrefslogtreecommitdiff
path: root/oslo_rootwrap/client.py
diff options
context:
space:
mode:
Diffstat (limited to 'oslo_rootwrap/client.py')
-rw-r--r--oslo_rootwrap/client.py49
1 files changed, 37 insertions, 12 deletions
diff --git a/oslo_rootwrap/client.py b/oslo_rootwrap/client.py
index b19d97f..ecf730f 100644
--- a/oslo_rootwrap/client.py
+++ b/oslo_rootwrap/client.py
@@ -47,11 +47,16 @@ class Client(object):
def __init__(self, rootwrap_daemon_cmd):
self._start_command = rootwrap_daemon_cmd
self._initialized = False
+ self._need_restart = False
self._mutex = threading.Lock()
self._manager = None
self._proxy = None
self._process = None
self._finalize = None
+ # This is for eventlet compatibility. multiprocessing stores
+ # daemon connection in ForkAwareLocal, so this won't be
+ # needed with the threading module.
+ self._exec_sem = threading.Lock()
def _initialize(self):
if self._process is not None and self._process.poll() is not None:
@@ -119,20 +124,40 @@ class Client(object):
self._proxy = None
self._initialized = False
self._initialize()
+ self._need_restart = False
return self._proxy
- def execute(self, cmd, stdin=None):
- self._ensure_initialized()
- proxy = self._proxy
- retry = False
+ def _run_one_command(self, proxy, cmd, stdin):
+ """Wrap proxy.run_one_command, setting _need_restart on an exception.
+
+ Usually it should be enough to drain stale data on socket
+ rather than to restart, but we cannot do draining easily.
+ """
try:
+ _need_restart = True
res = proxy.run_one_command(cmd, stdin)
- except (EOFError, IOError):
- retry = True
- # res can be None if we received final None sent by dying server thread
- # instead of response to our request. Process is most likely to be dead
- # at this point.
- if retry or res is None:
- proxy = self._restart(proxy)
- res = proxy.run_one_command(cmd, stdin)
+ _need_restart = False
+ return res
+ finally:
+ if _need_restart:
+ self._need_restart = True
+
+ def execute(self, cmd, stdin=None):
+ with self._exec_sem:
+ self._ensure_initialized()
+ proxy = self._proxy
+ retry = False
+ if self._need_restart:
+ proxy = self._restart(proxy)
+ try:
+ res = self._run_one_command(proxy, cmd, stdin)
+ except (EOFError, IOError):
+ retry = True
+ # res can be None if we received final None sent by dying
+ # server thread instead of response to our
+ # request. Process is most likely to be dead at this
+ # point.
+ if retry or res is None:
+ proxy = self._restart(proxy)
+ res = self._run_one_command(proxy, cmd, stdin)
return res