|
5 | 5 |
|
6 | 6 | import zenoh |
7 | 7 | from google.protobuf.message import Message |
8 | | -import concurrent.futures |
9 | 8 |
|
10 | 9 | from make87.session import get_session |
11 | 10 | from make87.utils import parse_endpoints, REQ, PRV, IS_IN_RELEASE_MODE, RingChannel, FifoChannel |
|
17 | 16 | class ProviderNotAvailable(Exception): ... |
18 | 17 |
|
19 | 18 |
|
| 19 | +class ResponseTimeout(Exception): ... |
| 20 | + |
| 21 | + |
20 | 22 | class Endpoint: |
21 | 23 | """Base class for endpoints.""" |
22 | 24 |
|
@@ -128,34 +130,35 @@ def __init__( |
128 | 130 | self._express = True if express is None else express |
129 | 131 |
|
130 | 132 | def request(self, message: zenoh.ZBytes, timeout: float = 10.0) -> zenoh.ZBytes: |
131 | | - subscriber = self._session.liveliness().declare_subscriber(key_expr=self.name, history=True) |
132 | | - |
133 | | - # Use the standard ThreadPoolExecutor to call subscriber.recv() with a timeout. |
134 | | - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: |
135 | | - future = executor.submit(subscriber.recv) |
136 | | - try: |
137 | | - sample = future.result(timeout=timeout) |
138 | | - except concurrent.futures.TimeoutError: |
139 | | - raise ProviderNotAvailable( |
140 | | - f"Endpoint '{self.name}' is not available. Timed out waiting for endpoint to become available." |
141 | | - ) |
142 | | - |
143 | | - if sample.kind != zenoh.SampleKind.PUT: |
144 | | - raise ProviderNotAvailable(f"Endpoint '{self.name}' is not available.") |
145 | | - |
146 | 133 | reply = self._session.get( |
147 | 134 | selector=self.name, |
148 | 135 | payload=message, |
149 | 136 | encoding=zenoh.Encoding.APPLICATION_PROTOBUF, |
150 | 137 | priority=self._priority, |
151 | 138 | express=self._express, |
152 | 139 | congestion_control=self._congestion_control, |
153 | | - ).recv() |
| 140 | + timeout=timeout, |
| 141 | + ) |
154 | 142 |
|
155 | 143 | try: |
| 144 | + reply = reply.recv() |
| 145 | + except zenoh.ZError as e: |
| 146 | + if all(token in str(e).upper() for token in ("CHANNEL", "CLOSED")): |
| 147 | + raise ProviderNotAvailable(f"Endpoint '{self.name}' is not available.") |
| 148 | + else: |
| 149 | + raise Exception(f"Error while requesting endpoint '{self.name}': {e}") |
| 150 | + |
| 151 | + if reply.ok is not None: |
156 | 152 | return reply.ok.payload |
157 | | - except Exception: |
158 | | - raise Exception(f"Failed to request endpoint '{self.name}': {reply.err.payload.to_string()}") |
| 153 | + elif reply.err is not None: |
| 154 | + if bytes(reply.err.payload).decode("utf-8").strip().upper() == "TIMEOUT": |
| 155 | + raise ResponseTimeout( |
| 156 | + f"Waited {timeout}s for response until timed out. Consider increasing your timeout or checking with the provider side." |
| 157 | + ) |
| 158 | + else: |
| 159 | + raise Exception( |
| 160 | + f"Error returned while requesting endpoint '{self.name}': {reply.err.payload.to_string()}" |
| 161 | + ) |
159 | 162 |
|
160 | 163 |
|
161 | 164 | class _EndpointManager: |
|
0 commit comments