Esempio n. 1
0
    def spawnNewChild(self):
        """
        STEP 1 (parent): New child spawning starts by killing the current
        child.
        """


        if not self.active:
            raise CannotSpawnNewChild("Loop not started yet")

        if self.forking:
            raise CannotSpawnNewChild("Serious forking action is already going on. Cannot fork now.")

        if self.child_pid is None:
            raise CannotSpawnNewChild("No killing yet. Not started child yet")


        self.pause = False

        if not self.killed_child or self.isChild():
            self._killChild()
        else:
            # Ok, we already have sent the SIGINT the child, but asking for new child
            logger.info("Not sending SIGINT because we already killed the child. Just scheduling new fork.")
            self._scheduleFork()

        self.killed_child = True
Esempio n. 2
0
    def spawnNewChild(self):
        """
        STEP 1 (parent): New child spawning starts by killing the current
        child.
        """

        if not self.active:
            raise CannotSpawnNewChild("Loop not started yet")

        if self.forking:
            raise CannotSpawnNewChild("Serious forking action is already "
                                      "going on. Cannot fork now.")

        if self.child_pid is None:
            raise CannotSpawnNewChild("No killing yet. Not started child yet")

        self.pause = False

        if not self.killed_child or self.isChild():
            self._killChild()
        else:
            # Ok, we already have sent the SIGINT the child, but asking for new
            # child
            logger.info("Not sending SIGINT because we already killed "
                        "the child. Just scheduling new fork.")
            self._scheduleFork()

        self.killed_child = True
Esempio n. 3
0
    def _parentExitHandler(self, signum=None, frame=None):
        if self.isChild():
            return

        self.exit = True

        if self.isChildAlive():
            logger.info("Parent dying. Killing child first.")
            self._killChild()
Esempio n. 4
0
    def _parentExitHandler(self, signum=None, frame=None):
        if self.isChild():
            return

        self.exit = True

        if self.isChildAlive():
            logger.info("Parent dying. Killing child first.")
            self._killChild()
Esempio n. 5
0
    def on_any_event(self, event):
        ext = event.src_path.split(".")[-1].lower()
        if ext not in self.allowed_extensions:
            return

        logger.info("Got '%s' event on %s" % (event.event_type, event.src_path))

        try:
            self.forkloop.spawnNewChild()
        except CannotSpawnNewChild as e:
            logger.error(str(e.args[0]))
Esempio n. 6
0
    def on_any_event(self, event):
        ext = event.src_path.split(".")[-1].lower()
        if ext not in self.allowed_extensions:
            return

        logger.info("Got '%s' event on %s" %
                    (event.event_type, event.src_path))

        try:
            self.forkloop.spawnNewChild()
        except CannotSpawnNewChild as e:
            logger.error(str(e.args[0]))
Esempio n. 7
0
    def start(self):
        """Start file monitoring thread"""

        registerHandler(signal.SIGINT, self._exitHandler)
        registerHandler(signal.SIGTERM, self._exitHandler)

        for path in self.paths:
            logger.info("Starting file monitor on %s" % path)
            observer = Observer()
            self.observers.append(observer)
            observer.schedule(self, path=path, recursive=True)
            observer.start()
 def _waitChildToDieAndScheduleNew(self, signal=None, frame=None):
     """
     STEP 3 (parent): Child told us via SIGCHLD that we can spawn new child
     """
     try:
         # Acknowledge dead child
         pid, exit_status = os.wait()
         logger.info("Child %d exited, reasons %s" % (pid, self._resolveExitReason(exit_status)))
     except OSError:
         # OSError: [Errno 10] No child processes
         pass
     # Schedule new
     self._scheduleFork()
Esempio n. 9
0
    def start(self):
        """
        Start file monitoring thread
        """

        registerHandler(signal.SIGINT, self._exitHandler)
        registerHandler(signal.SIGTERM, self._exitHandler)

        for path in self.paths:
            logger.info("Starting file monitor on %s" % path)
            observer = Observer()
            self.observers.append(observer)
            observer.schedule(self, path=path, recursive=True)
            observer.start()
Esempio n. 10
0
def startForkLoop(event):

    if not monkeypatcher.PATCHED:
        errline()
        errline("sauna.reload is not installed correctly!")
        errline("Your are missing following line from instance part "
                "of your buildout:")
        errline()
        errline("    zope-conf-additional = %import sauna.reload")
        errline()
        errline("Not starting fork loop.")
        errline()
        return

    if not reload_paths:
        errline()
        errline("sauna.reload: No paths in RELOAD_PATH environment variable. "
                "Not starting fork loop.")
        errline("Set it to your development egg paths to activate reloading")
        errline()
        errline("Example:")
        errline("         $ RELOAD_PATH=src/ bin/instance fg")
        errline()
        return

    # Start fs monitor before the forkloop
    watcher.Watcher(reload_paths.getParentPaths(), forkloop).start()

    # Build and execute a configuration file to include meta, configuration and
    # overrides for dependencies of the deferred development packages.
    autoinclude.includeDependenciesForDeferred()
    autoinclude.checkDeferringErrors()

    config = getConfiguration()
    zserver = [
        server for server in config.servers
        if isinstance(server, zhttp_server)
    ][0]

    logger.info("We saved at least %s seconds from boot up time" %
                (time.time() - forkloop.boot_started))

    logger.info("Overview available at http://127.0.0.1:%i/@@saunareload" %
                (zserver.port))

    forkloop.start()
    def on_any_event(self, event):
        ext = event.src_path.split(".")[-1].lower()
        if ext not in self.allowed_extensions:
            return

        logger.info("Got '%s' event on %s" %
            (event.event_type, event.src_path))

        if ext in ( "html", "xml" ):
            notify(ThemeChanged())
            logger.info("Signaling plone.app.theming")
            return

        try:
            self.forkloop.spawnNewChild()
        except CannotSpawnNewChild as e:
            logger.error(str(e.args[0]))
def startForkLoop(event):

    if not monkeypatcher.PATCHED:
        errline()
        errline("sauna.reload is not installed correctly!")
        errline("Your are missing following line from instance part "
                "of your buildout:")
        errline()
        errline("    zope-conf-additional = %import sauna.reload")
        errline()
        errline("Not starting fork loop.")
        errline()
        return

    if not reload_paths:
        errline()
        errline("sauna.reload: No paths in RELOAD_PATH environment variable. "
                "Not starting fork loop.")
        errline("Set it to your development egg paths to activate reloading")
        errline()
        errline("Example:")
        errline("         $ RELOAD_PATH=src/ bin/instance fg")
        errline()
        return

    # Start fs monitor before the forkloop
    watcher.Watcher(reload_paths.getParentPaths(), forkloop).start()

    # Build and execute a configuration file to include meta, configuration and
    # overrides for dependencies of the deferred development packages.
    autoinclude.includeDependenciesForDeferred()
    autoinclude.checkDeferringErrors()

    config = getConfiguration()
    zserver = [server for server in config.servers
        if isinstance(server, zhttp_server)][0]

    logger.info("We saved at least %s seconds from boot up time" %
        (time.time() - forkloop.boot_started))

    logger.info("Overview available at http://127.0.0.1:%i/@@saunareload" %
        (zserver.port))

    forkloop.start()
Esempio n. 13
0
    def loop(self):
        """
        Magic happens here
        """

        registerHandler(signal.SIGINT, self._parentExitHandler)
        registerHandler(signal.SIGTERM, self._parentExitHandler)

        self.active = True

        logger.info("Fork loop starting on parent. PID %i" % os.getpid())
        while True:
            self.forking = False

            if self.exit:
                return

            if self.fork:
                self.fork = False

                if self.pause:
                    # Pause mode. No forks now.
                    continue

                if not self.killed_child:
                    errline()
                    errline("Child died on bootup. Pausing fork loop for now. ")
                    errline("Fix possible errors and save edits and we'll try booting again.")
                    errline("Waiting...")

                    # Child died because of unknown reason. Mark it as killed
                    # and go into pause mode.
                    self.killed_child = True
                    self.pause = True
                    continue

                if self.isChildAlive():
                    # Child is still alive for some reason. Lets wait few
                    # rounds for it to die.
                    continue

                self.forking = True
                self.startChildBooTimer()
                self.child_pid = os.fork()
                if self.child_pid == 0:
                    break
                self.killed_child = False

            time.sleep(1)

        logger.setChildLogger()
        logger.info("Forked new child. Installing reloadable products...")

        self._prepareNewChild()

        self.forking = False

        logger.info("Booted up new new child in %s seconds. PID %i" % (
            time.time() - self.child_started,  os.getpid()))

        notify(NewChildIsReady(self))
Esempio n. 14
0
    def loop(self):
        """
        Magic happens here
        """

        registerHandler(signal.SIGINT, self._parentExitHandler)
        registerHandler(signal.SIGTERM, self._parentExitHandler)

        self.active = True

        logger.info("Fork loop starting on parent. PID %i" % os.getpid())
        while True:
            self.forking = False

            if self.exit:
                return

            if self.fork:
                self.fork = False

                if self.pause:
                    # Pause mode. No forks now.
                    continue

                if not self.killed_child:
                    errline()
                    errline("Child died on bootup. "
                            "Pausing fork loop for now.")
                    errline("Fix possible errors and save edits "
                            "and we'll try booting again.")
                    errline("Waiting...")

                    # Child died because of unknown reason. Mark it as killed
                    # and go into pause mode.
                    self.killed_child = True
                    self.pause = True
                    continue

                if self.isChildAlive():
                    # Child is still alive for some reason. Lets wait few
                    # rounds for it to die.
                    continue

                self.forking = True
                self.startChildBooTimer()
                self.child_pid = os.fork()
                if self.child_pid == 0:
                    break
                self.killed_child = False

            time.sleep(1)

        logger.setChildLogger()
        logger.info("Forked new child. Installing reloadable products...")

        self._prepareNewChild()

        self.forking = False

        logger.logDeferredErrors()
        logger.logDeferred()

        logger.info("Booted up new child in %s seconds. PID %i" %
                    (time.time() - self.child_started, os.getpid()))

        notify(NewChildIsReady(self))