The Node main method, running in a child process (similar to Process.run() but also accepts args)
        A children class can override this method, but it needs to call super().run(*args, **kwargs)
        for the node to start properly and call update() as expected.
        :param args: arguments to pass to update()
        :param kwargs: keyword arguments to pass to update()
        :return: last exitcode returned by update()

def run(self, *args, **kwargs):
        """
        The Node main method, running in a child process (similar to Process.run() but also accepts args)
        A children class can override this method, but it needs to call super().run(*args, **kwargs)
        for the node to start properly and call update() as expected.
        :param args: arguments to pass to update()
        :param kwargs: keyword arguments to pass to update()
        :return: last exitcode returned by update()
        """
        # TODO : make use of the arguments ? since run is now the target for Process...

        exitstatus = None  # keeping the semantic of multiprocessing.Process : running process has None

        if setproctitle and self.new_title:
            setproctitle.setproctitle("{0}".format(self.name))

        print('[{proc}] Proc started as [{pid}]'.format(proc=self.name, pid=self.ident))

        with self.context_manager(*args, **kwargs) as cm:
            if cm:
                cmargs = maybe_tuple(cm)
                # prepending context manager, to be able to access it from target
                args = cmargs + args

            exitstatus = self.eventloop(*args, **kwargs)

            logging.debug("[{self.name}] Proc exited.".format(**locals()))
            return exitstatus