Esempio n. 1
0
class ManagerControlled(object):

    def __init__(self, *args, **kwargs):
        self.context = Context.instance()
        self.loop = IOLoop.instance()
        self.control_socket = self.context.socket(SUB)
        self.control_socket.setsockopt(LINGER, 0)  # discard unsent messages on close
        self.control_socket.setsockopt(SUBSCRIBE, '')
        self.control_socket.connect('tcp://{}:{}'.format(MANAGER_PUB_ADDRESS, MANAGER_PUB_PORT))
        self.control_stream = ZMQStream(self.control_socket, self.loop)
        self.control_stream.on_recv_stream(self.control_handler)

    def control_handler(self, stream, message_list):
        for message in message_list:
            try:
                notification, data = message.split()
            except ValueError:
                notification = message

            if notification == NOTIFICATION_PROCESS_STOP:
                self.stop()

    def stop(self):
        self.control_stream.stop_on_recv()
        self.control_stream.close()
        self.control_socket.close()
Esempio n. 2
0
class Controller:
    def __init__(self, cfg, target=None, args=[]):
        (self.target, self.args) = (target, args)

        # Set up server socket
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.ROUTER)
        self.port = self.socket.bind_to_random_port('tcp://*',
                                                    min_port=cfg["port_min"],
                                                    max_port=cfg["port_max"],
                                                    max_tries=100)
        self.uri = "tcp://127.0.0.1:%d" % (self.port)
        print "Controller listening on %s" % (self.uri)

        self.start()

    def send_json(self, identity, obj):
        self.stream.send(identity, zmq.SNDMORE)
        self.stream.send_json(obj)

    def start(self):
        # Launch worker subprocesses
        self.processes = dict(
            zip(self.args, map(lambda x: self.target(x, self.uri), self.args)))
        for d, p in self.processes.iteritems():
            print "Launching Worker: ", d
            p.start()

        # Start IOLoop
        self.stream = ZMQStream(self.socket)
        self.ioloop = ioloop.IOLoop.instance()
        self.ioloop.call_later(1.0, self.on_start)
        self.stream.on_recv_stream(self.on_rcv)
        try:
            self.ioloop.start()
        except KeyboardInterrupt:
            print " ** Got keyboard interrupt (^C) shutting down cleanly ... ** "
            self.shutdown()
        self.ioloop.close()
        for d, p in self.processes.iteritems():
            p.join()

    def on_start(self):
        print "Controller: start doing stuff"

    def on_rcv(self, stream, msg):
        [identity, msg] = msg
        #print identity,msg
        msg = json.loads(msg)
        op = msg[0]
        if (hasattr(self, "on_" + op)):
            f = getattr(self, "on_" + op)
            args = [identity] + msg[1:]
            f(*args)
        else:
            print "Controller received invalid command: ", msg

    def shutdown(self):
        #self.socket.send_json( ("shutdown",) )
        self.ioloop.stop()
Esempio n. 3
0
def main():    
    import sys
    from PyQt4 import QtGui, Qt
    
    from eventloop import QtLoop, ZMQLoop
    from kernel import Kernel
    from epubsub.hub import Hub
    
    import zmq
    from zmq.eventloop.zmqstream import ZMQStream 
    

    
    def callback(stream, msg):
        print msg
        stream.send('OK')
        
    print 'running'
    #app = QtGui.QApplication(sys.argv)

    loop = ZMQLoop()
    loop.install()
    kernel = Kernel()
    
    ctx = zmq.Context()
    socket = ctx.socket(zmq.ROUTER)
    socket.bind('tcp://127.0.0.1:11111')
    stream = ZMQStream(socket)
    
    stream.on_recv_stream(callback)
    loop.start()
Esempio n. 4
0
def rec(port):

    zmq_ctx = zmq.Context()

    s = zmq_ctx.socket(zmq.SUB)
    s.bind('tcp://*:{port}'.format(port=port))
    s.setsockopt(zmq.SUBSCRIBE, b"")

    stream = ZMQStream(s)

    stream.on_recv_stream(rec_frame)

    ioloop.IOLoop.instance().start()

    while True:
        pass
Esempio n. 5
0
 def bind(self, interface):
     context = zmq.Context()
     socket = context.socket(zmq.REP)
     socket.bind(interface)
     stream = ZMQStream(socket)
     stream.on_recv_stream(self.dispatch)
Esempio n. 6
0
class KernelNanny:
    """Object for monitoring

    Must be child of engine

    Handles signal messages and watches Engine process for exiting
    """
    def __init__(
        self,
        *,
        pid: int,
        engine_id: int,
        control_url: str,
        registration_url: str,
        identity: bytes,
        curve_serverkey: bytes,
        curve_publickey: bytes,
        curve_secretkey: bytes,
        config: Config,
        pipe,
        log_level: int = logging.INFO,
    ):
        self.pid = pid
        self.engine_id = engine_id
        self.parent_process = psutil.Process(self.pid)
        self.control_url = control_url
        self.registration_url = registration_url
        self.identity = identity
        self.curve_serverkey = curve_serverkey
        self.curve_publickey = curve_publickey
        self.curve_secretkey = curve_secretkey
        self.config = config
        self.pipe = pipe
        self.session = Session(config=self.config)

        self.log = local_logger(f"{self.__class__.__name__}.{engine_id}",
                                log_level)
        self.log.propagate = False

        self.control_handlers = {
            "signal_request": self.signal_request,
        }
        self._finish_called = False

    def wait_for_parent_thread(self):
        """Wait for my parent to exit, then I'll notify the controller and shut down"""
        self.log.info(f"Nanny watching parent pid {self.pid}.")
        while True:
            try:
                exit_code = self.parent_process.wait(60)
            except psutil.TimeoutExpired:
                continue
            else:
                break
        self.log.critical(f"Parent {self.pid} exited with status {exit_code}.")
        self.loop.add_callback(self.finish)

    def pipe_handler(self, fd, events):
        self.log.debug(f"Pipe event {events}")
        self.loop.remove_handler(fd)
        try:
            fd.close()
        except BrokenPipeError:
            pass
        try:
            status = self.parent_process.wait(0)
        except psutil.TimeoutExpired:
            try:
                status = self.parent_process.status()
            except psutil.NoSuchProcess:
                status = "exited"

        self.log.critical(
            f"Pipe closed, parent {self.pid} has status: {status}")
        self.finish()

    def notify_exit(self):
        """Notify the Hub that our parent has exited"""
        self.log.info("Notifying Hub that our parent has shut down")
        s = self.context.socket(zmq.DEALER)
        # finite, nonzero LINGER to prevent hang without dropping message during exit
        s.LINGER = 3000
        util.connect(
            s,
            self.registration_url,
            curve_serverkey=self.curve_serverkey,
            curve_secretkey=self.curve_secretkey,
            curve_publickey=self.curve_publickey,
        )
        self.session.send(s,
                          "unregistration_request",
                          content={"id": self.engine_id})
        s.close()

    def finish(self):
        """Prepare to exit and stop our event loop."""
        if self._finish_called:
            return
        self._finish_called = True
        self.notify_exit()
        self.loop.add_callback(self.loop.stop)

    def dispatch_control(self, stream, raw_msg):
        """Dispatch message from the control scheduler

        If we have a handler registered"""
        try:
            idents, msg_frames = self.session.feed_identities(raw_msg)
        except Exception as e:
            self.log.error(f"Bad control message: {raw_msg}", exc_info=True)
            return

        try:
            msg = self.session.deserialize(msg_frames, content=True)
        except Exception:
            content = error.wrap_exception()
            self.log.error("Bad control message: %r",
                           msg_frames,
                           exc_info=True)
            return

        msg_type = msg['header']['msg_type']
        if msg_type.endswith("_request"):
            reply_type = msg_type[-len("_request"):]
        else:
            reply_type = "error"
        self.log.debug(f"Client {idents[-1]} requested {msg_type}")

        handler = self.control_handlers.get(msg_type, None)
        if handler is None:
            # don't have an intercept handler, relay original message to parent
            self.log.debug(f"Relaying {msg_type} {msg['header']['msg_id']}")
            self.parent_stream.send_multipart(raw_msg)
            return

        try:
            content = handler(msg['content'])
        except Exception:
            content = error.wrap_exception()
            self.log.error("Error handling request: %r",
                           msg_type,
                           exc_info=True)

        self.session.send(stream,
                          reply_type,
                          ident=idents,
                          content=content,
                          parent=msg)

    def dispatch_parent(self, stream, raw_msg):
        """Relay messages from parent directly to control stream"""
        self.control_stream.send_multipart(raw_msg)

    # intercept message handlers

    def signal_request(self, content):
        """Handle a signal request: send signal to parent process"""
        sig = content['sig']
        if isinstance(sig, str):
            sig = getattr(signal, sig)
        self.log.info(f"Sending signal {sig} to pid {self.pid}")
        # exception will be caught and wrapped by the caller
        self.parent_process.send_signal(sig)
        return {"status": "ok"}

    def start(self):
        self.log.info(
            f"Starting kernel nanny for engine {self.engine_id}, pid={self.pid}, nanny pid={os.getpid()}"
        )
        self._watcher_thread = Thread(target=self.wait_for_parent_thread,
                                      name="WatchParent",
                                      daemon=True)
        self._watcher_thread.start()
        # ignore SIGINT sent to parent
        signal.signal(signal.SIGINT, signal.SIG_IGN)

        self.loop = IOLoop.current()
        self.context = zmq.Context()

        # set up control socket (connection to Scheduler)
        self.control_socket = self.context.socket(zmq.ROUTER)
        self.control_socket.identity = self.identity
        util.connect(
            self.control_socket,
            self.control_url,
            curve_serverkey=self.curve_serverkey,
        )
        self.control_stream = ZMQStream(self.control_socket)
        self.control_stream.on_recv_stream(self.dispatch_control)

        # set up relay socket (connection to parent's control socket)
        self.parent_socket = self.context.socket(zmq.DEALER)
        if self.curve_secretkey:
            self.parent_socket.setsockopt(zmq.CURVE_SERVER, 1)
            self.parent_socket.setsockopt(zmq.CURVE_SECRETKEY,
                                          self.curve_secretkey)

        port = self.parent_socket.bind_to_random_port("tcp://127.0.0.1")

        # now that we've bound, pass port to parent via AsyncResult
        self.pipe.write(f"tcp://127.0.0.1:{port}\n")
        if not sys.platform.startswith("win"):
            # watch for the stdout pipe to close
            # as a signal that our parent is shutting down
            self.loop.add_handler(self.pipe, self.pipe_handler,
                                  IOLoop.READ | IOLoop.ERROR)
        self.parent_stream = ZMQStream(self.parent_socket)
        self.parent_stream.on_recv_stream(self.dispatch_parent)
        try:
            self.loop.start()
        finally:
            self.loop.close(all_fds=True)
            self.context.term()
            try:
                self.pipe.close()
            except BrokenPipeError:
                pass
            self.log.debug("exiting")

    @classmethod
    def main(cls, *args, **kwargs):
        """Main body function.

        Instantiates and starts a nanny.

        Args and keyword args passed to the constructor.

        Should be called in a subprocess.
        """
        # start a new event loop for the forked process
        asyncio.set_event_loop(asyncio.new_event_loop())
        IOLoop().make_current()
        self = cls(*args, **kwargs)
        self.start()
Esempio n. 7
0
 def bind(self, port):
     context = zmq.Context()
     socket = context.socket(zmq.REP)
     socket.bind(port)
     stream = ZMQStream(socket)
     stream.on_recv_stream(self.dispatch)
Esempio n. 8
0
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://127.0.0.1:5556")
stream = ZMQStream(socket)


def echo(stream, msg):
    global this
    global last
    this = int(time.time())

    global tc
    global total
    tc += 1
    total += 1

    if this != last:
        print str(tc) + ' ' + str(total)
        tc = 0
        last = this
    # stream.send_multipart(msg)

stream.on_recv_stream(echo)


def send():
    stream.send(b"Hello")
    ioloop.IOLoop.instance().add_callback(send)

ioloop.IOLoop.instance().add_callback(send)
ioloop.IOLoop.instance().start()
Esempio n. 9
0
File: app.py Progetto: vvsha/w29
    if sys.argv[1] == 'server':
        # Setup a REP ZMQ socket
        context = zmq.Context()
        socket = context.socket(zmq.REP)
        socket.bind('tcp://127.0.0.1:8889')
        # See http://zeromq.github.io/pyzmq/eventloop.html

        # Setup the event loop
        # loop = tornado.ioloop.IOLoop.instance()
        ioloop.install()

        # Add a ZMQStream made from the socket to the event loop
        stream = ZMQStream(socket)

        # Register recv callback
        stream.on_recv_stream(recv_callback_stream)

        # How to add a periodic callback to the event loop
        periodic = ioloop.PeriodicCallback(periodic_callback, 1000)

        # periodic_callback will be called each second
        periodic.start()

        # Setup tornado webserver on :8888
        app.listen(8888)
        # And start the event loop
        print 'Open a browser to http://localhost:8888'
        ioloop.IOLoop.instance().start()

    elif sys.argv[1] == 'client':
        if len(sys.argv) != 5:
    if sys.argv[1] == 'server':
        # Setup a REP ZMQ socket
        context = zmq.Context()
        socket = context.socket(zmq.REP)
        socket.bind('tcp://127.0.0.1:8889')
        # See http://zeromq.github.io/pyzmq/eventloop.html

        # Setup the event loop
        # loop = tornado.ioloop.IOLoop.instance()
        ioloop.install()

        # Add a ZMQStream made from the socket to the event loop
        stream = ZMQStream(socket)

        # Register recv callback
        stream.on_recv_stream(recv_callback_stream)

        # How to add a periodic callback to the event loop
        periodic = ioloop.PeriodicCallback(periodic_callback, 1000)

        # periodic_callback will be called each second
        periodic.start()

        # Setup tornado webserver on :8888
        app.listen(8888)
        # And start the event loop
        print 'Open a browser to http://localhost:8888'
        ioloop.IOLoop.instance().start()

    elif sys.argv[1] == 'client':
        if len(sys.argv) != 5:
Esempio n. 11
0
        socket.send_multipart(msg)
        time.sleep(0.1)

run_event = threading.Event()
run_event.set()

t = threading.Thread(target=threaded_loop)
t.daemon = False
t.start()

# listeners can request the knownStreams dictionary on a req-rep socket
info_socket = context.socket(zmq.REP)
info_socket.bind("tcp://*:5557")

info_stream = ZMQStream(info_socket)
info_stream.on_recv_stream(processInfoMsg)

try:
    ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
    print("Halt signal detected. Cleaning up...")
except:
    print "Exception in server code:"
    print '-'*60
    traceback.print_exc(file=sys.stdout)
    print '-'*60
    print("Cleaning up...")
finally:
    run_event.clear()
    t.join()
    info_socket.close()
Esempio n. 12
0
        time.sleep(0.1)


run_event = threading.Event()
run_event.set()

t = threading.Thread(target=threaded_loop)
t.daemon = False
t.start()

# listeners can request the knownStreams dictionary on a req-rep socket
info_socket = context.socket(zmq.REP)
info_socket.bind("tcp://*:5557")

info_stream = ZMQStream(info_socket)
info_stream.on_recv_stream(processInfoMsg)

try:
    ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
    print("Halt signal detected. Cleaning up...")
except:
    print "Exception in server code:"
    print '-' * 60
    traceback.print_exc(file=sys.stdout)
    print '-' * 60
    print("Cleaning up...")
finally:
    run_event.clear()
    t.join()
    info_socket.close()