socketflow 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {socketflow-0.2.1 → socketflow-0.2.2}/PKG-INFO +1 -1
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/__init__.py +1 -1
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/client_side/client.py +13 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/blueprint.py +16 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/event_loop.py +14 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/transport.py +11 -2
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/server_side/server.py +17 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/PKG-INFO +1 -1
- {socketflow-0.2.1 → socketflow-0.2.2}/README.md +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/setup.cfg +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/setup.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/client_side/__init__.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/__init__.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/compression.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/dispatcher.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/event.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/exceptions.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/logs.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/message_handler.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/message_manager.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/metrics.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/protocol.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/server_side/__init__.py +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/SOURCES.txt +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/dependency_links.txt +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/not-zip-safe +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/requires.txt +0 -0
- {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/top_level.txt +0 -0
|
@@ -235,6 +235,12 @@ class TcpClientProtocol:
|
|
|
235
235
|
with self._control_lock:
|
|
236
236
|
self.socket.sendall(data)
|
|
237
237
|
|
|
238
|
+
def has_backpressure(self) -> bool:
|
|
239
|
+
"""True when the outbound queue to the server is full."""
|
|
240
|
+
if self._writer is None:
|
|
241
|
+
return False
|
|
242
|
+
return self._writer.has_backpressure()
|
|
243
|
+
|
|
238
244
|
def close(self):
|
|
239
245
|
self._writer.abort()
|
|
240
246
|
|
|
@@ -986,6 +992,13 @@ class TcpClient:
|
|
|
986
992
|
def is_connected(self):
|
|
987
993
|
return self._connected
|
|
988
994
|
|
|
995
|
+
def has_backpressure(self) -> bool:
|
|
996
|
+
"""True when the outbound queue to the server is full."""
|
|
997
|
+
protocol = self._protocol
|
|
998
|
+
if protocol is None:
|
|
999
|
+
return False
|
|
1000
|
+
return protocol.has_backpressure()
|
|
1001
|
+
|
|
989
1002
|
@property
|
|
990
1003
|
def handshake_completed(self):
|
|
991
1004
|
return self._handshake_completed
|
|
@@ -78,6 +78,22 @@ class Blueprint:
|
|
|
78
78
|
"Blueprint not registered with client or server"
|
|
79
79
|
)
|
|
80
80
|
|
|
81
|
+
def has_backpressure(self, client_addr: tuple = None) -> bool:
|
|
82
|
+
"""True when the outbound queue is full.
|
|
83
|
+
|
|
84
|
+
On a server blueprint, client_addr selects the client to check.
|
|
85
|
+
"""
|
|
86
|
+
if hasattr(self, "_client") and self._client:
|
|
87
|
+
return self._client.has_backpressure()
|
|
88
|
+
elif hasattr(self, "_server") and self._server:
|
|
89
|
+
if not client_addr:
|
|
90
|
+
raise ExceptionType.BlueprintError("client_addr parameter is required")
|
|
91
|
+
return self._server.has_backpressure(client_addr)
|
|
92
|
+
else:
|
|
93
|
+
raise ExceptionType.BlueprintError(
|
|
94
|
+
"Blueprint not registered with client or server"
|
|
95
|
+
)
|
|
96
|
+
|
|
81
97
|
def send(
|
|
82
98
|
self,
|
|
83
99
|
data: Any,
|
|
@@ -176,6 +176,12 @@ class EventLoopWriter:
|
|
|
176
176
|
return True
|
|
177
177
|
return self.connection.flush(timeout)
|
|
178
178
|
|
|
179
|
+
def has_backpressure(self) -> bool:
|
|
180
|
+
"""True when the next send would raise Backpressure."""
|
|
181
|
+
if self.connection is None:
|
|
182
|
+
return False
|
|
183
|
+
return self.connection.has_backpressure()
|
|
184
|
+
|
|
179
185
|
def abort(self, timeout=1.0):
|
|
180
186
|
if self.connection is not None:
|
|
181
187
|
self.connection.close()
|
|
@@ -233,6 +239,14 @@ class _SelectorConnection:
|
|
|
233
239
|
with self._lock:
|
|
234
240
|
return self._pending_writes
|
|
235
241
|
|
|
242
|
+
def has_backpressure(self) -> bool:
|
|
243
|
+
"""True when the next send would raise Backpressure."""
|
|
244
|
+
with self._lock:
|
|
245
|
+
return (
|
|
246
|
+
self._pending_writes >= self._max_pending_writes
|
|
247
|
+
or self._queued_bytes >= self._max_queue_bytes
|
|
248
|
+
)
|
|
249
|
+
|
|
236
250
|
def flush(self, timeout: float = 5.0) -> bool:
|
|
237
251
|
"""Wait until the send buffer is empty.
|
|
238
252
|
|
|
@@ -50,7 +50,6 @@ class MemoryBudget:
|
|
|
50
50
|
self._used_bytes = max(0, self._used_bytes - amount)
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
|
|
54
53
|
class TimeoutScheduler:
|
|
55
54
|
"""Run request timeouts from a single shared thread.
|
|
56
55
|
|
|
@@ -217,7 +216,9 @@ class PendingResponseRegistry:
|
|
|
217
216
|
key = self._key(data_id, owner)
|
|
218
217
|
with self._lock:
|
|
219
218
|
if key in self._responses:
|
|
220
|
-
raise ValueError(
|
|
219
|
+
raise ValueError(
|
|
220
|
+
f"A request with data_id {data_id!r} is already pending"
|
|
221
|
+
)
|
|
221
222
|
self._responses[key] = future
|
|
222
223
|
|
|
223
224
|
def pop(self, data_id: str, owner: Any = None) -> Optional[Any]:
|
|
@@ -335,6 +336,14 @@ class SocketWriter:
|
|
|
335
336
|
return False
|
|
336
337
|
time.sleep(0.002)
|
|
337
338
|
|
|
339
|
+
def has_backpressure(self) -> bool:
|
|
340
|
+
"""True when the next send would raise Backpressure."""
|
|
341
|
+
with self._state_lock:
|
|
342
|
+
return (
|
|
343
|
+
self._pending_writes >= self._max_pending_writes
|
|
344
|
+
or self._queued_bytes >= self._max_queue_bytes
|
|
345
|
+
)
|
|
346
|
+
|
|
338
347
|
def _complete(self, payload: bytes):
|
|
339
348
|
with self._state_lock:
|
|
340
349
|
self._queued_bytes -= len(payload)
|
|
@@ -436,6 +436,12 @@ class TcpServerProtocol:
|
|
|
436
436
|
except Exception:
|
|
437
437
|
return False
|
|
438
438
|
|
|
439
|
+
def has_backpressure(self) -> bool:
|
|
440
|
+
"""True when the outbound queue to this client is full."""
|
|
441
|
+
if self._writer is None:
|
|
442
|
+
return False
|
|
443
|
+
return self._writer.has_backpressure()
|
|
444
|
+
|
|
439
445
|
def close(self):
|
|
440
446
|
if self._writer is not None:
|
|
441
447
|
self._writer.abort()
|
|
@@ -1432,6 +1438,17 @@ class TcpServer:
|
|
|
1432
1438
|
with self._clients_lock:
|
|
1433
1439
|
return client_addr in self._clients
|
|
1434
1440
|
|
|
1441
|
+
def has_backpressure(self, client_addr) -> bool:
|
|
1442
|
+
"""True when the outbound queue to one client is full.
|
|
1443
|
+
|
|
1444
|
+
Returns False when the client is not connected.
|
|
1445
|
+
"""
|
|
1446
|
+
with self._clients_lock:
|
|
1447
|
+
protocol = self._clients.get(client_addr)
|
|
1448
|
+
if protocol is None:
|
|
1449
|
+
return False
|
|
1450
|
+
return protocol.has_backpressure()
|
|
1451
|
+
|
|
1435
1452
|
def get_client_identity(self, client_addr: tuple) -> Optional[str]:
|
|
1436
1453
|
"""Return the verified certificate common name for a client, or None."""
|
|
1437
1454
|
with self._clients_lock:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|