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.
Files changed (28) hide show
  1. {socketflow-0.2.1 → socketflow-0.2.2}/PKG-INFO +1 -1
  2. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/__init__.py +1 -1
  3. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/client_side/client.py +13 -0
  4. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/blueprint.py +16 -0
  5. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/event_loop.py +14 -0
  6. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/transport.py +11 -2
  7. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/server_side/server.py +17 -0
  8. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/PKG-INFO +1 -1
  9. {socketflow-0.2.1 → socketflow-0.2.2}/README.md +0 -0
  10. {socketflow-0.2.1 → socketflow-0.2.2}/setup.cfg +0 -0
  11. {socketflow-0.2.1 → socketflow-0.2.2}/setup.py +0 -0
  12. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/client_side/__init__.py +0 -0
  13. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/__init__.py +0 -0
  14. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/compression.py +0 -0
  15. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/dispatcher.py +0 -0
  16. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/event.py +0 -0
  17. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/exceptions.py +0 -0
  18. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/logs.py +0 -0
  19. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/message_handler.py +0 -0
  20. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/message_manager.py +0 -0
  21. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/metrics.py +0 -0
  22. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/global_side/protocol.py +0 -0
  23. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow/server_side/__init__.py +0 -0
  24. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/SOURCES.txt +0 -0
  25. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/dependency_links.txt +0 -0
  26. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/not-zip-safe +0 -0
  27. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/requires.txt +0 -0
  28. {socketflow-0.2.1 → socketflow-0.2.2}/socketflow.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketflow
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: TCP networking for Python, without the boilerplate.
5
5
  Home-page: https://github.com/ayammaximilian/socketflow
6
6
  Author: SocketFlow Team
@@ -34,7 +34,7 @@ from .global_side.protocol import (
34
34
  MAX_PROTOCOL_VERSION,
35
35
  )
36
36
 
37
- __version__ = "0.2.1"
37
+ __version__ = "0.2.2"
38
38
  __all__ = [
39
39
  "TcpServer",
40
40
  "TcpClient",
@@ -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(f"A request with data_id {data_id!r} is already pending")
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketflow
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: TCP networking for Python, without the boilerplate.
5
5
  Home-page: https://github.com/ayammaximilian/socketflow
6
6
  Author: SocketFlow Team
File without changes
File without changes
File without changes