remoteRF-server 1.1.0.dev49__py3-none-any.whl → 1.1.0.dev50__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.
- remoteRF_server/server/direct_path.py +23 -3
- {remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/METADATA +1 -1
- {remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/RECORD +7 -7
- {remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/WHEEL +0 -0
- {remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/entry_points.txt +0 -0
- {remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/licenses/LICENSE +0 -0
- {remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/top_level.txt +0 -0
|
@@ -74,6 +74,21 @@ async def close_ice(ice) -> None:
|
|
|
74
74
|
await ice.close()
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
async def cancel_tasks(tasks) -> None:
|
|
78
|
+
"""Cancel these tasks and wait for them to finish.
|
|
79
|
+
|
|
80
|
+
A task that is cancelled but never awaited can be collected while still
|
|
81
|
+
pending, and Python prints a traceback for it that nobody can act on.
|
|
82
|
+
The caller's own task is never cancelled, so this is safe to call from
|
|
83
|
+
inside one of the tasks being torn down."""
|
|
84
|
+
current = asyncio.current_task()
|
|
85
|
+
tasks = [task for task in tasks if task is not None and task is not current and not task.done()]
|
|
86
|
+
for task in tasks:
|
|
87
|
+
task.cancel()
|
|
88
|
+
if tasks:
|
|
89
|
+
await asyncio.gather(*tasks, return_exceptions=True)
|
|
90
|
+
|
|
91
|
+
|
|
77
92
|
def quiet_aioice_errors(loop) -> None:
|
|
78
93
|
"""A STUN retry on an already-closed socket is not an error worth a
|
|
79
94
|
traceback in someone's shell; everything else keeps the default handler."""
|
|
@@ -248,6 +263,7 @@ class _Path:
|
|
|
248
263
|
self.calls = 0
|
|
249
264
|
self.task: Optional[asyncio.Task] = None
|
|
250
265
|
self.transport: Optional[_IceTransport] = None
|
|
266
|
+
self.streams: set[asyncio.Task] = set()
|
|
251
267
|
|
|
252
268
|
async def run(self) -> None:
|
|
253
269
|
protocol = None
|
|
@@ -266,8 +282,7 @@ class _Path:
|
|
|
266
282
|
printf(f"Direct path open: {self.user} from {self.peer[0]}:{self.peer[1]} ({where})", Sty.GRAY)
|
|
267
283
|
await asyncio.wait({pump, closed}, return_when=asyncio.FIRST_COMPLETED)
|
|
268
284
|
finally:
|
|
269
|
-
pump
|
|
270
|
-
closed.cancel()
|
|
285
|
+
await cancel_tasks((pump, closed))
|
|
271
286
|
except Exception as exc: # noqa: BLE001 - a failed punch is expected on some networks
|
|
272
287
|
printf(f"Direct path failed: {self.user}: {type(exc).__name__}: {exc}", Sty.GRAY)
|
|
273
288
|
finally:
|
|
@@ -308,7 +323,11 @@ class _Path:
|
|
|
308
323
|
protocol.datagram_received(data, self.peer)
|
|
309
324
|
|
|
310
325
|
def _stream(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
|
|
311
|
-
|
|
326
|
+
# Tracked, not fire-and-forget: a stream holds a device call, and the
|
|
327
|
+
# path may close under it.
|
|
328
|
+
task = asyncio.ensure_future(self._serve(reader, writer))
|
|
329
|
+
self.streams.add(task)
|
|
330
|
+
task.add_done_callback(self.streams.discard)
|
|
312
331
|
|
|
313
332
|
async def _serve(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
|
|
314
333
|
bad_frame = None
|
|
@@ -344,6 +363,7 @@ class _Path:
|
|
|
344
363
|
task.cancel()
|
|
345
364
|
with contextlib.suppress(asyncio.CancelledError):
|
|
346
365
|
await task
|
|
366
|
+
await cancel_tasks(list(self.streams))
|
|
347
367
|
await close_ice(self.ice)
|
|
348
368
|
|
|
349
369
|
|
|
@@ -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=
|
|
59
|
+
remoteRF_server/server/direct_path.py,sha256=TrL0aWCUXN9Lmuww-v_AXtLIOqTkckm2vPW91xcnOLI,17875
|
|
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.
|
|
94
|
-
remoterf_server-1.1.0.
|
|
95
|
-
remoterf_server-1.1.0.
|
|
96
|
-
remoterf_server-1.1.0.
|
|
97
|
-
remoterf_server-1.1.0.
|
|
98
|
-
remoterf_server-1.1.0.
|
|
93
|
+
remoterf_server-1.1.0.dev50.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
94
|
+
remoterf_server-1.1.0.dev50.dist-info/METADATA,sha256=jy_xvhBrCSFGJ5x5I_ZBgDynd1Hwe7uFv-1KaC-Fs60,42069
|
|
95
|
+
remoterf_server-1.1.0.dev50.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
96
|
+
remoterf_server-1.1.0.dev50.dist-info/entry_points.txt,sha256=_bbKk65PfYi-n6zUjqOiOwcalf_Ws1TCGATIe1TukxE,136
|
|
97
|
+
remoterf_server-1.1.0.dev50.dist-info/top_level.txt,sha256=NuYWe8dSx3qdbxshWBwOgx68EHmJ9I8Zvxam4ARsQ_I,30
|
|
98
|
+
remoterf_server-1.1.0.dev50.dist-info/RECORD,,
|
|
File without changes
|
{remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{remoterf_server-1.1.0.dev49.dist-info → remoterf_server-1.1.0.dev50.dist-info}/top_level.txt
RENAMED
|
File without changes
|