A Queue-like container for IPC using ZeroMQ.
| 20 | |
| 21 | |
| 22 | class ZeroMqQueue: |
| 23 | ''' A Queue-like container for IPC using ZeroMQ. ''' |
| 24 | |
| 25 | socket_type_str = { |
| 26 | zmq.PAIR: "PAIR", |
| 27 | zmq.PULL: "PULL", |
| 28 | zmq.PUSH: "PUSH", |
| 29 | zmq.ROUTER: "ROUTER", |
| 30 | zmq.DEALER: "DEALER", |
| 31 | } |
| 32 | |
| 33 | def __init__(self, |
| 34 | address: Optional[tuple[str, Optional[bytes]]] = None, |
| 35 | *, |
| 36 | socket_type: int = zmq.PAIR, |
| 37 | is_server: bool, |
| 38 | is_async: bool = False, |
| 39 | name: Optional[str] = None, |
| 40 | use_hmac_encryption: bool = True): |
| 41 | ''' |
| 42 | Parameters: |
| 43 | address (tuple[str, Optional[bytes]], optional): The address (tcp-ip_port, hmac_auth_key) for the IPC. Defaults to None. If hmac_auth_key is None and use_hmac_encryption is False, the queue will not use HMAC encryption. |
| 44 | socket_type (int): The type of socket to use. Defaults to zmq.PAIR. |
| 45 | is_server (bool): Whether the current process is the server or the client. |
| 46 | is_async (bool): Whether to use asyncio for the socket. Defaults to False. |
| 47 | name (str, optional): The name of the queue. Defaults to None. |
| 48 | use_hmac_encryption (bool): Whether to use HMAC encryption for pickled data. Defaults to True. |
| 49 | ''' |
| 50 | |
| 51 | self.socket_type = socket_type |
| 52 | self.address_endpoint = address[ |
| 53 | 0] if address is not None else "tcp://127.0.0.1:*" |
| 54 | self.is_server = is_server |
| 55 | self.context = zmq.Context() if not is_async else zmq.asyncio.Context() |
| 56 | self.poller = None |
| 57 | self.socket = None |
| 58 | |
| 59 | self._setup_done = False |
| 60 | self.name = name |
| 61 | self.socket = self.context.socket(socket_type) |
| 62 | self.socket.set_hwm(0) |
| 63 | |
| 64 | # For ROUTER sockets, track the last identity to enable replies. For now we assume there is only one client in our case. |
| 65 | self._last_identity = None |
| 66 | |
| 67 | self.hmac_key = address[1] if address is not None else None |
| 68 | self.use_hmac_encryption = use_hmac_encryption |
| 69 | |
| 70 | self._setup_lock = threading.Lock() |
| 71 | |
| 72 | # Thread safety debugging |
| 73 | self._zmq_thread_id = None |
| 74 | self._zmq_debug_enabled = os.environ.get('TLLM_LLMAPI_ZMQ_DEBUG', |
| 75 | '0') != '0' |
| 76 | |
| 77 | # Check HMAC key condition |
| 78 | if self.use_hmac_encryption and not self.is_server and self.hmac_key is None: |
| 79 | raise ValueError( |
no outgoing calls