def connect(self): Resource.connect(self) self._thread = LightThread(target=self._thread_proc, name="{0:s}:?".format(self.name)) self._thread.start() self._ready.wait( 3.0) # this may spend waiting slightly less, but it's ok if not self._ready.is_set(): self._queue.push( exit) # just in case the thread has in fact started raise Exception("new thread failed to start in 3.0 seconds")
def primary_startup( node_cage: by_regex("^[A-Za-z0-9_-]{1,32}(\\.[A-Za-z0-9_-]{1,32})?$")): if "." in node_cage: # node name is specified explicitly node, cage = node_cage.split(".") else: # node name is taken from the environment cage = node_cage node = node_name().split(".")[0] cage_dir = os_path.join(cages_dir, cage) # cage directory must exist if not os_path.isdir(cage_dir): raise Exception("cage directory does not exist") logs_dir = os_path.join( cage_dir, "logs") # while logs directory will be created if necessary if not os_path.isdir(logs_dir): try: mkdir(logs_dir) except OSError as e: if e.errno != EEXIST: raise # write own pid file, this also serves as a test of the logs directory writability with open(os_path.join(logs_dir, "{0:s}.pid".format(cage)), "wb") as f: f.write("{0:d}".format(getpid()).encode("ascii")) restarting_after_failure = False # performing normal startup by default while True: # keep starting secondary startup script until it exits successfully def drain_stream(stream): try: while stream.read(512): pass except: pass # just exit # pass the same arguments to the same script, only prefixing them with dash startup_py = popen(python, os_path.join(pmnc_dir, "startup.py"), "-", node, cage, restarting_after_failure and "FAILURE" or "NORMAL") # any output from the secondary script is ignored stdout_reader = LightThread(target=drain_stream, args=(startup_py.stdout, )) stdout_reader.start() stderr_reader = LightThread(target=drain_stream, args=(startup_py.stderr, )) stderr_reader.start() # wait for the secondary script to terminate while startup_py.poll() is None: try: sleep( 3.0 ) # fails with "interrupted system call" at logoff when started as win32 service except: pass stdout_reader.join(3.0) # should have exited with eof stderr_reader.join(3.0) # or broken pipe, but who knows if startup_py.wait() != 0: restarting_after_failure = True # set the flag and restart the secondary script else: break # successful exit
def _start_adapter(self, adapter_usage, adapter_name, start_timeout): pmnc.log.info("starting adapter process for {0:s} {1:s}".\ format(adapter_usage, adapter_name)) if pmnc.log.debug: pmnc.log.debug("adapter process command line: {0:s}".format(" ".join(self._args))) self._adapter = popen(*self._args) # start the java process try: if pmnc.log.debug: pmnc.log.debug("adapter process (pid {0:d}) has started".\ format(self._adapter.pid)) # the process has started and its initialization is underway # create light threads for controlling stdin/out/err, these # threads are not stopped explicitly but exit when the adapter # exits and the pipes break self._stdin_queue = InterlockedQueue() self._stdin_writer = LightThread(target = self._stdin_writer_proc, args = (self._adapter.stdin, self._stdin_queue), name = "{0:s}:stdin".format(adapter_name)) self._stdin_writer.start() self._stdout_queue = InterlockedQueue() self._stdout_reader = LightThread(target = self._stdout_reader_proc, args = (self._adapter.stdout, self._stdin_queue), name = "{0:s}:stdout".format(adapter_name)) self._stdout_reader.start() self._stderr_queue = InterlockedQueue() self._stderr_reader = LightThread(target = self._stderr_reader_proc, args = (self._adapter.stderr, ), name = "{0:s}:stderr".format(adapter_name)) self._stderr_reader.start() # wait for the adapter to come up and report readiness while not start_timeout.expired: pkt = self._stdout_queue.pop(min(0.5, start_timeout.remain)) if pkt is None: # see whether the adapter has exited if not self._adapter_running(): retcode = self._adapter.wait() if retcode is not None: raise Exception("adapter process exited with " "retcode {0:d}".format(retcode)) elif "XPmncError" in pkt: raise Exception(pkt["XPmncError"]) elif pkt.get("XPmncStatus") == "READY": break else: raise Exception("adapter process returned invalid status") else: raise Exception("timeout waiting for adapter process to initialize") except: self._stop_adapter(start_timeout) # what remained of start timeout is used for stopping raise pmnc.log.info("adapter process (pid {0:d}) is ready".format(self._adapter.pid))