remoteRF-server 1.1.0.dev47__py3-none-any.whl → 1.1.0.dev49__py3-none-any.whl

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.
@@ -50,6 +50,43 @@ from .global_onboarding import RELAYED, hostname, is_offsite
50
50
 
51
51
  logger = logging.getLogger("remoteRF_server.direct")
52
52
 
53
+
54
+ async def close_ice(ice) -> None:
55
+ """Close an aioice Connection without the library's after-close noise.
56
+
57
+ A cancelled ``connect()`` (a punch that timed out) never reaches aioice's
58
+ own "cancel remaining checks" loop, so its check tasks keep running and
59
+ its STUN timers stay armed against sockets close() is about to take. Stop
60
+ both before closing."""
61
+ # Cancel the connectivity checks first. Failing their STUN transactions
62
+ # instead only makes aioice start replacement checks, which then hang on
63
+ # a closed socket and die "pending" when they are collected.
64
+ checks = [pair.task for pair in list(getattr(ice, "_check_list", [])) if pair.task is not None]
65
+ for task in checks:
66
+ task.cancel()
67
+ if checks:
68
+ await asyncio.gather(*checks, return_exceptions=True)
69
+ for protocol in list(getattr(ice, "_protocols", [])):
70
+ for transaction in list(getattr(protocol, "transactions", {}).values()):
71
+ handle = getattr(transaction, "_Transaction__timeout_handle", None)
72
+ if handle is not None:
73
+ handle.cancel() # a retry would fire on the socket close() is about to take
74
+ await ice.close()
75
+
76
+
77
+ def quiet_aioice_errors(loop) -> None:
78
+ """A STUN retry on an already-closed socket is not an error worth a
79
+ traceback in someone's shell; everything else keeps the default handler."""
80
+ default = loop.default_exception_handler
81
+
82
+ def handler(loop, context):
83
+ exc = context.get("exception")
84
+ if isinstance(exc, (AttributeError, OSError)) and "Transaction" in repr(context.get("handle", "")):
85
+ return
86
+ default(context)
87
+
88
+ loop.set_exception_handler(handler)
89
+
53
90
  ALPN = "remoterf-direct/1"
54
91
  MAX_FRAME = 100 * 1024 * 1024 # the gRPC message ceiling
55
92
  IDLE_SECONDS = 600
@@ -307,7 +344,7 @@ class _Path:
307
344
  task.cancel()
308
345
  with contextlib.suppress(asyncio.CancelledError):
309
346
  await task
310
- await self.ice.close()
347
+ await close_ice(self.ice)
311
348
 
312
349
 
313
350
  async def _offer(key: str, user: str, remote: dict) -> dict:
@@ -327,7 +364,7 @@ async def _offer(key: str, user: str, remote: dict) -> dict:
327
364
  await ice.add_remote_candidate(Candidate.from_sdp(str(sdp)))
328
365
  await ice.add_remote_candidate(None)
329
366
  except Exception:
330
- await ice.close()
367
+ await close_ice(ice)
331
368
  raise
332
369
  path = _paths[key] = _Path(key, user, ice)
333
370
  path.task = asyncio.ensure_future(path.run())
@@ -343,6 +380,7 @@ def _get_loop() -> asyncio.AbstractEventLoop:
343
380
  with _lock:
344
381
  if _loop is None:
345
382
  _loop = asyncio.new_event_loop()
383
+ quiet_aioice_errors(_loop)
346
384
  threading.Thread(
347
385
  target=_loop.run_forever, name="remoterf-direct", daemon=True
348
386
  ).start()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remoteRF-server
3
- Version: 1.1.0.dev47
3
+ Version: 1.1.0.dev49
4
4
  Summary: RemoteRF server-side control package
5
5
  License: GPL-3.0-or-later
6
6
  Classifier: Programming Language :: Python :: 3
@@ -56,7 +56,7 @@ remoteRF_server/server/commands.py,sha256=ccb_Ab1mbIkosBsFGJnDSccrjWtR_Lymvvn3Iq
56
56
  remoteRF_server/server/console.py,sha256=J91LfwPVmBgielOxfE740NOYduekggyZkqi-47y_A4w,4472
57
57
  remoteRF_server/server/control.py,sha256=Uq1Fk0zIoHHX_EXfz3OuNle8urvO_UhAiB5Lk5cs2e4,5177
58
58
  remoteRF_server/server/device_manager.py,sha256=PPuCwlPSmjfVpCqy_hCaOr9WvFgE8mqtLMhWOAgXNDA,39281
59
- remoteRF_server/server/direct_path.py,sha256=CQs0uPTANJq6Bn-TzsV0APmD3hYKH8xYvczXZZk1OXk,15229
59
+ remoteRF_server/server/direct_path.py,sha256=VNujG1xMc5dj8xkZJG9AXyV0FzIyEo3OsUv7AVPu1Qo,16959
60
60
  remoteRF_server/server/dynamic_v2.py,sha256=AMhQEFhNAvCNcF-PdfCCQQLmeoaR7s1Os8et1KFGn_8,70814
61
61
  remoteRF_server/server/global_onboarding.py,sha256=NcKG8TYhCJEiaCtdXL1jEgVm-R_xWpOIj5KI4bWfkr0,39942
62
62
  remoteRF_server/server/grpc_server.py,sha256=91FpJubzN_Wfuk6fW_owIEzNCukd333sAGW68FUU8pk,46787
@@ -90,9 +90,9 @@ remoteRF_server/tools/gen_certs.py,sha256=Vbyu8JjRu__UYPVmyCRXt5SOw0Za1HV7g1md3G
90
90
  remoteRF_server/tools/gist_status.py,sha256=SFv2iQgQrIKT9gxKrU-_Dr7S0p0rE4wQM6J3OC6FcoM,4649
91
91
  remoteRF_server/tools/gist_status_testing.py,sha256=IYw7UkPjAUpKDTtIlnYGb5g6SJkwz4TRGUfJJ6f4LhQ,2690
92
92
  remoteRF_server/tools/introspect_uhd.py,sha256=vUpPb0rM9tsHPxWadS3EfMDE-gMd-TvNV0TjrZOQqBY,4531
93
- remoterf_server-1.1.0.dev47.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
94
- remoterf_server-1.1.0.dev47.dist-info/METADATA,sha256=jRJsAiJF90sOYqLqwlGY7P7wa5bohJWgoEnoN_KMqnI,42069
95
- remoterf_server-1.1.0.dev47.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
96
- remoterf_server-1.1.0.dev47.dist-info/entry_points.txt,sha256=_bbKk65PfYi-n6zUjqOiOwcalf_Ws1TCGATIe1TukxE,136
97
- remoterf_server-1.1.0.dev47.dist-info/top_level.txt,sha256=NuYWe8dSx3qdbxshWBwOgx68EHmJ9I8Zvxam4ARsQ_I,30
98
- remoterf_server-1.1.0.dev47.dist-info/RECORD,,
93
+ remoterf_server-1.1.0.dev49.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
94
+ remoterf_server-1.1.0.dev49.dist-info/METADATA,sha256=bfmyOSKZdas4E-wiTwUyXzbhtVJfF9Ev4kVjHU3UXXI,42069
95
+ remoterf_server-1.1.0.dev49.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
96
+ remoterf_server-1.1.0.dev49.dist-info/entry_points.txt,sha256=_bbKk65PfYi-n6zUjqOiOwcalf_Ws1TCGATIe1TukxE,136
97
+ remoterf_server-1.1.0.dev49.dist-info/top_level.txt,sha256=NuYWe8dSx3qdbxshWBwOgx68EHmJ9I8Zvxam4ARsQ_I,30
98
+ remoterf_server-1.1.0.dev49.dist-info/RECORD,,