|
5 | 5 | from zmq.utils.monitor import recv_monitor_message
|
6 | 6 | import time
|
7 | 7 | import uuid
|
8 |
| -from .DebugLog import Debug, Error |
| 8 | +from .DebugLog import Debug, Error, Info |
9 | 9 | from .Config import xsub_url, xpub_url, router_url
|
10 | 10 | from typing import Any, Dict
|
11 | 11 |
|
12 | 12 |
|
13 |
| -class ActorConnector: |
| 13 | +class ActorSender: |
14 | 14 | def __init__(self, context, topic):
|
15 | 15 | self._context = context
|
16 |
| - |
17 |
| - self._resp_socket = self._context.socket(zmq.SUB) |
18 |
| - self._resp_socket.setsockopt(zmq.LINGER, 0) |
19 |
| - self._resp_socket.setsockopt(zmq.RCVTIMEO, 250) |
20 |
| - self._resp_socket.connect(xpub_url) |
21 |
| - self._resp_topic = str(uuid.uuid4()) |
22 |
| - Debug("AgentConnector", f"subscribe to: {self._resp_topic}") |
23 |
| - self._resp_socket.setsockopt_string(zmq.SUBSCRIBE, f"{self._resp_topic}") |
24 | 16 | self._topic = topic
|
25 |
| - |
26 | 17 | self._connect_pub_socket()
|
27 | 18 |
|
28 |
| - def _send_recv_router_msg(self): |
29 |
| - # Send a request to the router and wait for a response |
30 |
| - req_socket = self._context.socket(zmq.REQ) |
31 |
| - req_socket.connect(router_url) |
32 |
| - try: |
33 |
| - Debug("ActorConnector", "Broker Check Request Sent") |
34 |
| - req_socket.send_string("Request") |
35 |
| - _ = req_socket.recv_string() |
36 |
| - Debug("ActorConnector", "Broker Check Response Received") |
37 |
| - finally: |
38 |
| - req_socket.close() |
39 |
| - |
40 | 19 | def _connect_pub_socket(self):
|
| 20 | + Debug("ActorSender", f"Connecting pub socket {self._topic}") |
41 | 21 | self._pub_socket = self._context.socket(zmq.PUB)
|
42 |
| - self._pub_socket.setsockopt(zmq.LINGER, 0) |
43 | 22 | monitor = self._pub_socket.get_monitor_socket()
|
| 23 | + self._pub_socket.setsockopt(zmq.LINGER, 0) |
44 | 24 | self._pub_socket.connect(xsub_url)
|
45 | 25 | # Monitor handshake on the pub socket
|
46 | 26 | while monitor.poll():
|
47 | 27 | evt: Dict[str, Any] = {}
|
48 | 28 | mon_evt = recv_monitor_message(monitor)
|
49 | 29 | evt.update(mon_evt)
|
50 | 30 | if evt["event"] == zmq.EVENT_MONITOR_STOPPED or evt["event"] == zmq.EVENT_HANDSHAKE_SUCCEEDED:
|
51 |
| - Debug("ActorConnector", "Handshake received (Or Monitor stopped)") |
| 31 | + Debug("ActorSender", "Handshake received (Or Monitor stopped)") |
52 | 32 | break
|
53 | 33 | self._pub_socket.disable_monitor()
|
54 | 34 | monitor.close()
|
55 | 35 | self._send_recv_router_msg()
|
56 | 36 |
|
| 37 | + def _send_recv_router_msg(self): |
| 38 | + # Send a request to the router and wait for a response |
| 39 | + req_socket = self._context.socket(zmq.REQ) |
| 40 | + req_socket.connect(router_url) |
| 41 | + try: |
| 42 | + Debug("ActorSender", "Broker Check Request Sent") |
| 43 | + req_socket.send_string("Request") |
| 44 | + _ = req_socket.recv_string() |
| 45 | + Debug("ActorSender", "Broker Check Response Received") |
| 46 | + finally: |
| 47 | + req_socket.close() |
| 48 | + |
57 | 49 | def send_txt_msg(self, msg):
|
| 50 | + Debug("ActorSender", f"[{self._topic}] send_txt_msg: {msg}") |
58 | 51 | self._pub_socket.send_multipart(
|
59 |
| - [self._topic.encode("utf8"), "text".encode("utf8"), self._resp_topic.encode("utf8"), msg.encode("utf8")] |
| 52 | + [self._topic.encode("utf8"), "text".encode("utf8"), "no_resp".encode("utf8"), msg.encode("utf8")] |
60 | 53 | )
|
61 | 54 |
|
62 | 55 | def send_bin_msg(self, msg_type: str, msg):
|
| 56 | + Debug("ActorSender", f"[{self._topic}] send_bin_msg: {msg_type}") |
63 | 57 | self._pub_socket.send_multipart(
|
64 |
| - [self._topic.encode("utf8"), msg_type.encode("utf8"), self._resp_topic.encode("utf8"), msg] |
| 58 | + [self._topic.encode("utf8"), msg_type.encode("utf8"), "no_resp".encode("utf8"), msg] |
65 | 59 | )
|
66 | 60 |
|
67 |
| - def binary_request(self, msg_type: str, msg, retry=5): |
| 61 | + def send_bin_request_msg(self, msg_type: str, msg, resp_topic: str): |
| 62 | + Debug("ActorSender", f"[{self._topic}] send_bin_request_msg: {msg_type}") |
68 | 63 | self._pub_socket.send_multipart(
|
69 |
| - [self._topic.encode("utf8"), msg_type.encode("utf8"), self._resp_topic.encode("utf8"), msg] |
| 64 | + [self._topic.encode("utf8"), msg_type.encode("utf8"), resp_topic.encode("utf8"), msg] |
70 | 65 | )
|
71 |
| - for i in range(retry + 1): |
72 |
| - try: |
73 |
| - resp_topic, resp_msg_type, resp_sender_topic, resp = self._resp_socket.recv_multipart() |
74 |
| - return resp_topic, resp_msg_type, resp_sender_topic, resp |
75 |
| - except zmq.Again: |
76 |
| - Debug("ActorConnector", f"binary_request: No response received. retry_count={i}, max_retry={retry}") |
77 |
| - time.sleep(0.01) # Wait a bit before retrying |
78 |
| - continue |
79 |
| - Error("ActorConnector", "binary_request: No response received. Giving up.") |
80 |
| - return None, None, None, None |
81 | 66 |
|
82 | 67 | def close(self):
|
83 | 68 | self._pub_socket.close()
|
| 69 | + |
| 70 | + |
| 71 | +class ActorConnector: |
| 72 | + def __init__(self, context, topic): |
| 73 | + self._context = context |
| 74 | + self._topic = topic |
| 75 | + self._connect_sub_socket() |
| 76 | + self._sender = ActorSender(context, topic) |
| 77 | + time.sleep(0.1) # Wait for the socket to connect |
| 78 | + |
| 79 | + def _connect_sub_socket(self): |
| 80 | + self._resp_socket = self._context.socket(zmq.SUB) |
| 81 | + monitor = self._resp_socket.get_monitor_socket() |
| 82 | + self._resp_socket.setsockopt(zmq.LINGER, 0) |
| 83 | + self._resp_socket.setsockopt(zmq.RCVTIMEO, 250) |
| 84 | + self._resp_socket.connect(xpub_url) |
| 85 | + self._resp_topic = str(uuid.uuid4()) |
| 86 | + Debug("ActorConnector", f"subscribe to: {self._resp_topic}") |
| 87 | + self._resp_socket.setsockopt_string(zmq.SUBSCRIBE, f"{self._resp_topic}") |
| 88 | + while monitor.poll(): |
| 89 | + evt: Dict[str, Any] = {} |
| 90 | + mon_evt = recv_monitor_message(monitor) |
| 91 | + evt.update(mon_evt) |
| 92 | + Debug("ActorConnector", evt) |
| 93 | + if evt["event"] == zmq.EVENT_MONITOR_STOPPED or evt["event"] == zmq.EVENT_HANDSHAKE_SUCCEEDED: |
| 94 | + Debug("ActorConnector", "Handshake received (Or Monitor stopped)") |
| 95 | + break |
| 96 | + self._resp_socket.disable_monitor() |
| 97 | + monitor.close() |
| 98 | + self._send_recv_router_msg() |
| 99 | + |
| 100 | + def _send_recv_router_msg(self): |
| 101 | + # Send a request to the router and wait for a response |
| 102 | + req_socket = self._context.socket(zmq.REQ) |
| 103 | + req_socket.connect(router_url) |
| 104 | + try: |
| 105 | + Debug("ActorConnector", "Broker Check Request Sent") |
| 106 | + req_socket.send_string("Request") |
| 107 | + _ = req_socket.recv_string() |
| 108 | + Debug("ActorConnector", "Broker Check Response Received") |
| 109 | + finally: |
| 110 | + req_socket.close() |
| 111 | + |
| 112 | + def send_txt_msg(self, msg): |
| 113 | + self._sender.send_txt_msg(msg) |
| 114 | + |
| 115 | + def send_bin_msg(self, msg_type: str, msg): |
| 116 | + self._sender.send_bin_msg(msg_type, msg) |
| 117 | + |
| 118 | + def binary_request(self, msg_type: str, msg, retry=5): |
| 119 | + original_timeout: int = 0 |
| 120 | + if retry == -1: |
| 121 | + original_timeout = self._resp_socket.getsockopt(zmq.RCVTIMEO) |
| 122 | + self._resp_socket.setsockopt(zmq.RCVTIMEO, 1000) |
| 123 | + |
| 124 | + try: |
| 125 | + self._sender.send_bin_request_msg(msg_type, msg, self._resp_topic) |
| 126 | + while retry == -1 or retry > 0: |
| 127 | + try: |
| 128 | + topic, resp_msg_type, _, resp = self._resp_socket.recv_multipart() |
| 129 | + return topic, resp_msg_type, resp |
| 130 | + except zmq.Again: |
| 131 | + Debug( |
| 132 | + "ActorConnector", f"{self._topic}: No response received. retry_count={retry}, max_retry={retry}" |
| 133 | + ) |
| 134 | + time.sleep(0.01) |
| 135 | + if retry != -1: |
| 136 | + retry -= 1 |
| 137 | + finally: |
| 138 | + if retry == -1: |
| 139 | + self._resp_socket.setsockopt(zmq.RCVTIMEO, original_timeout) |
| 140 | + |
| 141 | + Error("ActorConnector", f"{self._topic}: No response received. Giving up.") |
| 142 | + return None, None, None |
| 143 | + |
| 144 | + def close(self): |
| 145 | + self._sender.close() |
84 | 146 | self._resp_socket.close()
|
0 commit comments