Esempio n. 1
0
    def __init__(self, name, params, cwd=None, env=None, debug=False, shell=False, bufsize=-1):
        self.name = name
        self.service_stopped = Signal("stopped signal for " + strings.quote(name))
        self.stdin = Queue("stdin for process " + strings.quote(name), silent=True)
        self.stdout = Queue("stdout for process " + strings.quote(name), silent=True)
        self.stderr = Queue("stderr for process " + strings.quote(name), silent=True)

        try:
            self.debug = debug or DEBUG
            self.service = service = subprocess.Popen(
                [str(p) for p in params],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                bufsize=bufsize,
                cwd=cwd if isinstance(cwd, (str, NullType, none_type)) else cwd.abspath,
                env={str(k): str(v) for k, v in set_default(env, os.environ).items()},
                shell=shell
            )

            self.please_stop = Signal()
            self.please_stop.on_go(self._kill)
            self.thread_locker = Lock()
            self.children = [
                Thread.run(self.name + " stdin", self._writer, service.stdin, self.stdin, please_stop=self.service_stopped, parent_thread=self),
                Thread.run(self.name + " stdout", self._reader, "stdout", service.stdout, self.stdout, please_stop=self.service_stopped, parent_thread=self),
                Thread.run(self.name + " stderr", self._reader, "stderr", service.stderr, self.stderr, please_stop=self.service_stopped, parent_thread=self),
                Thread.run(self.name + " waiter", self._monitor, parent_thread=self),
            ]
        except Exception as e:
            Log.error("Can not call", e)

        self.debug and Log.note("{{process}} START: {{command}}", process=self.name, command=" ".join(map(strings.quote, params)))
Esempio n. 2
0
    def __init__(self, name, target, *args, **kwargs):
        self.id = -1
        self.name = name
        self.target = target
        self.end_of_thread = None
        self.synch_lock = Lock("response synch lock")
        self.args = args

        # ENSURE THERE IS A SHARED please_stop SIGNAL
        self.kwargs = copy(kwargs)
        self.kwargs["please_stop"] = self.kwargs.get(
            "please_stop", Signal("please_stop for " + self.name))
        self.please_stop = self.kwargs["please_stop"]

        self.thread = None
        self.stopped = Signal("stopped signal for " + self.name)
        self.cprofiler = Null
        self.children = []

        if "parent_thread" in kwargs:
            del self.kwargs["parent_thread"]
            self.parent = kwargs["parent_thread"]
        else:
            self.parent = Thread.current()
            self.parent.add_child(self)
Esempio n. 3
0
    def wait(self, till=None):
        """
        THE ASSUMPTION IS wait() WILL ALWAYS RETURN WITH THE LOCK ACQUIRED
        :param till: WHEN TO GIVE UP WAITING FOR ANOTHER THREAD TO SIGNAL
        :return: True IF SIGNALED TO GO, False IF TIMEOUT HAPPENED
        """
        waiter = Signal()
        if self.waiting:
            if DEBUG:
                _Log.note("{{name}} waiting with others", name=self.name)
            self.waiting.insert(0, waiter)
        else:
            self.waiting = [waiter]

        try:
            self.lock.release()
            (waiter | till).wait()
            if DEBUG:
                trace = _extract_stack(0)[2]
                _Log.note(
                    "{{name|quote}} out of lock waiting till {{till|quote}}\n{{trace}} ",
                    till=till.name if till else "",
                    name=self.name,
                    trace=trace)
        except Exception, e:
            if not _Log:
                _late_import()
            _Log.warning("problem", cause=e)
Esempio n. 4
0
 def __init__(self):
     self.name = "Main Thread"
     self.id = get_ident()
     self.please_stop = Signal()
     self.children = []
     self.stop_logging = Log.stop
     self.timers = None
     self.cprofiler = Null
Esempio n. 5
0
    def __init__(self, name, target, *args, **kwargs):
        BaseThread.__init__(self, -1)
        self.name = coalesce(name, "thread_" + text_type(object.__hash__(self)))
        self.target = target
        self.end_of_thread = Data()
        self.synch_lock = Lock("response synch lock")
        self.args = args

        # ENSURE THERE IS A SHARED please_stop SIGNAL
        self.kwargs = copy(kwargs)
        self.kwargs["please_stop"] = self.kwargs.get("please_stop", Signal("please_stop for " + self.name))
        self.please_stop = self.kwargs["please_stop"]

        self.thread = None
        self.stopped = Signal("stopped signal for " + self.name)

        if "parent_thread" in kwargs:
            del self.kwargs["parent_thread"]
            self.parent = kwargs["parent_thread"]
        else:
            self.parent = Thread.current()
            self.parent.add_child(self)
Esempio n. 6
0
 def __init__(self, name, max=None, silent=False, unique=False, allow_add_after_close=False):
     """
     max - LIMIT THE NUMBER IN THE QUEUE, IF TOO MANY add() AND extend() WILL BLOCK
     silent - COMPLAIN IF THE READERS ARE TOO SLOW
     unique - SET True IF YOU WANT ONLY ONE INSTANCE IN THE QUEUE AT A TIME
     """
     self.name = name
     self.max = coalesce(max, 2 ** 10)
     self.silent = silent
     self.allow_add_after_close=allow_add_after_close
     self.unique = unique
     self.please_stop = Signal("stop signal for " + name)
     self.lock = Lock("lock for queue " + name)
     self.queue = deque()
     self.next_warning = time()  # FOR DEBUGGING
Esempio n. 7
0
class Till(Signal):
    """
    TIMEOUT AS A SIGNAL
    """
    __slots__ = []

    locker = _allocate_lock()
    next_ping = time()
    done = Signal("Timers shutdown")
    enabled = False
    new_timers = []

    def __new__(cls, till=None, timeout=None, seconds=None):
        if not Till.enabled:
            return Till.done
        elif till == None and timeout == None and seconds == None:
            return None
        else:
            return object.__new__(cls)

    def __init__(self, till=None, timeout=None, seconds=None):
        now = time()
        if till != None:
            if not isinstance(till, (float, int)):
                from mo_logs import Log

                Log.error("Date objects for Till are no longer allowed")
            timeout = till
        elif seconds != None:
            timeout = now + seconds
        elif timeout != None:
            if not isinstance(timeout, (float, int)):
                from mo_logs import Log

                Log.error("Duration objects for Till are no longer allowed")

            timeout = now + timeout
        else:
            from mo_logs import Log
            Log.error("Should not happen")

        Signal.__init__(self, name=text_type(timeout))

        with Till.locker:
            if timeout != None:
                Till.next_ping = min(Till.next_ping, timeout)
            Till.new_timers.append((timeout, ref(self)))
Esempio n. 8
0
    def wait(self, till=None):
        """
        THE ASSUMPTION IS wait() WILL ALWAYS RETURN WITH THE LOCK ACQUIRED
        :param till: WHEN TO GIVE UP WAITING FOR ANOTHER THREAD TO SIGNAL
        :return: True IF SIGNALED TO GO, False IF TIMEOUT HAPPENED
        """
        waiter = Signal()
        if self.waiting:
            if DEBUG:
                _Log.note("waiting with {{num}} others on {{name|quote}}",
                          num=len(self.waiting),
                          name=self.name)
            self.waiting.insert(0, waiter)
        else:
            if DEBUG:
                _Log.note("waiting by self on {{name|quote}}", name=self.name)
            self.waiting = [waiter]

        try:
            self.lock.release()
            if DEBUG:
                _Log.note("out of lock {{name|quote}}", name=self.name)
            (waiter | till).wait()
            if DEBUG:
                _Log.note("done minimum wait (for signal {{till|quote}})",
                          till=till.name if till else "",
                          name=self.name)
        except Exception as e:
            if not _Log:
                _late_import()
            _Log.warning("problem", cause=e)
        finally:
            self.lock.acquire()
            if DEBUG:
                _Log.note("re-acquired lock {{name|quote}}", name=self.name)

        try:
            self.waiting.remove(waiter)
            if DEBUG:
                _Log.note("removed own signal from {{name|quote}}",
                          name=self.name)
        except Exception:
            pass

        return bool(waiter)
Esempio n. 9
0
    def wait_for_shutdown_signal(
        please_stop=False,  # ASSIGN SIGNAL TO STOP EARLY
        allow_exit=False,  # ALLOW "exit" COMMAND ON CONSOLE TO ALSO STOP THE APP
        wait_forever=True  # IGNORE CHILD THREADS, NEVER EXIT.  False -> IF NO CHILD THREADS LEFT, THEN EXIT
    ):
        """
        FOR USE BY PROCESSES NOT EXPECTED TO EVER COMPLETE UNTIL EXTERNAL
        SHUTDOWN IS REQUESTED

        SLEEP UNTIL keyboard interrupt, OR please_stop, OR "exit"

        :param please_stop:
        :param allow_exit:
        :param wait_forever:: Assume all needed threads have been launched. When done
        :return:
        """
        if not isinstance(please_stop, Signal):
            please_stop = Signal()

        please_stop.on_go(
            lambda: thread.start_new_thread(_stop_main_thread, ()))

        self_thread = Thread.current()
        if self_thread != MAIN_THREAD:
            Log.error(
                "Only the main thread can sleep forever (waiting for KeyboardInterrupt)"
            )

        if not wait_forever:
            # TRIGGER SIGNAL WHEN ALL EXITING THREADS ARE DONE
            pending = copy(self_thread.children)
            all = AndSignals(please_stop, len(pending))
            for p in pending:
                p.stopped.on_go(all.done)

        try:
            if allow_exit:
                _wait_for_exit(please_stop)
            else:
                _wait_for_interrupt(please_stop)
        except (KeyboardInterrupt, SystemExit), _:
            Log.alert("SIGINT Detected!  Stopping...")
Esempio n. 10
0
 def __init__(self):
     BaseThread.__init__(self, get_ident())
     self.name = "Main Thread"
     self.please_stop = Signal()
     self.stop_logging = Log.stop
     self.timers = None
Esempio n. 11
0
    def __init__(self,
                 name,
                 params,
                 cwd=None,
                 env=None,
                 debug=False,
                 shell=False,
                 bufsize=-1):
        self.name = name
        self.service_stopped = Signal("stopped signal for " +
                                      string2quote(name))
        self.stdin = Queue("stdin for process " + string2quote(name),
                           silent=True)
        self.stdout = Queue("stdout for process " + string2quote(name),
                            silent=True)
        self.stderr = Queue("stderr for process " + string2quote(name),
                            silent=True)

        try:
            self.debug = debug or DEBUG
            self.service = service = subprocess.Popen(
                params,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                bufsize=bufsize,
                cwd=cwd if isinstance(cwd, (basestring, NullType,
                                            NoneType)) else cwd.abspath,
                env=unwrap(set_default(env, os.environ)),
                shell=shell)

            self.please_stop = Signal()
            self.please_stop.on_go(self._kill)
            self.thread_locker = Lock()
            self.children = [
                Thread.run(self.name + " stdin",
                           self._writer,
                           service.stdin,
                           self.stdin,
                           please_stop=self.service_stopped,
                           parent_thread=self),
                Thread.run(self.name + " stdout",
                           self._reader,
                           "stdout",
                           service.stdout,
                           self.stdout,
                           please_stop=self.service_stopped,
                           parent_thread=self),
                Thread.run(self.name + " stderr",
                           self._reader,
                           "stderr",
                           service.stderr,
                           self.stderr,
                           please_stop=self.service_stopped,
                           parent_thread=self),
                Thread.run(self.name + " waiter",
                           self._monitor,
                           parent_thread=self),
            ]
        except Exception, e:
            Log.error("Can not call", e)
Esempio n. 12
0
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

from thread import allocate_lock as _allocate_lock
from time import sleep, time

from mo_threads.signal import Signal

DEBUG = False
INTERVAL = 0.1

_till_locker = _allocate_lock()
next_ping = time()
done = Signal("Timers shutdown")
done.go()


class Till(Signal):
    """
    TIMEOUT AS A SIGNAL
    """
    enabled = False
    new_timers = []

    def __new__(cls, till=None, timeout=None, seconds=None):
        if not Till.enabled:
            return done
        elif till is None and timeout is None and seconds is None:
            return None