Esempio n. 1
0
 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")
Esempio n. 2
0
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
Esempio n. 3
0
    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))