from queue import Queue import zmq import json from threading import Thread, Event from remote_command cimport RemoteCommand cdef class RemoteCommandHandler: def __init__(self, object on_command): self._on_command = on_command self._context = zmq.Context.instance() self._shutdown_event = Event() self._pull_socket = self._context.socket(zmq.PULL) self._pull_socket.setsockopt(zmq.LINGER, 0) self._pull_socket.bind("tcp://*:5127") self._pull_thread = Thread(target=self._pull_loop, daemon=True) self._push_queue = Queue() self._push_socket = self._context.socket(zmq.PUSH) self._push_socket.setsockopt(zmq.LINGER, 0) self._push_socket.bind("tcp://*:5128") self._push_thread = Thread(target=self._push_loop, daemon=True) cdef start(self): self._pull_thread.start() self._push_thread.start() cdef _pull_loop(self): while not self._shutdown_event.is_set(): print('wait for the command...') message = self._pull_socket.recv() cmd = RemoteCommand.from_msgpack(message) print(f'received: {cmd}') self._on_command(cmd) cdef _push_loop(self): while not self._shutdown_event.is_set(): try: response = self._push_queue.get(timeout=1) # Timeout to check shutdown flag self._push_socket.send(response) except: continue cdef send(self, bytes message_bytes): print(f'about to send {len(message_bytes)}') try: self._push_queue.put(message_bytes) except Exception as e: print(e) cdef close(self): self._shutdown_event.set() self._pull_socket.close() self._push_socket.close() self._context.term() cdef class QueueConfig: cdef str host, cdef int port, command_port cdef str producer_user, producer_pw, consumer_user, consumer_pw @staticmethod cdef QueueConfig from_json(str json_string): s = str(json_string).strip() cdef dict config_dict = json.loads(s)["QueueConfig"] cdef QueueConfig config = QueueConfig() config.host = config_dict["Host"] config.port = config_dict["Port"] config.command_port = config_dict["CommandsPort"] config.producer_user = config_dict["ProducerUsername"] config.producer_pw = config_dict["ProducerPassword"] config.consumer_user = config_dict["ConsumerUsername"] config.consumer_pw = config_dict["ConsumerPassword"] return config