@@ -51,10 +51,14 @@ def sync(loop, func, *args, timeout=None, **kwargs):
51
51
result = [None ]
52
52
event = threading .Event ()
53
53
asyncio .run_coroutine_threadsafe (_runner (event , coro , result , timeout ), loop )
54
- # Raise FSTimeoutError on event.wait() returns None (timeout) or
55
- # asyncio.TimeoutError to make the timeout behaviors consistency.
56
- if not event .wait (timeout ):
57
- raise FSTimeoutError
54
+ while True :
55
+ # this loops allows thread to get interrupted
56
+ if event .wait (1 ):
57
+ break
58
+ if timeout is not None :
59
+ timeout -= 1
60
+ if timeout < 0 :
61
+ raise FSTimeoutError
58
62
if isinstance (result [0 ], asyncio .TimeoutError ):
59
63
# suppress asyncio.TimeoutError, raise FSTimeoutError
60
64
raise FSTimeoutError
@@ -572,3 +576,43 @@ def mirror_sync_methods(obj):
572
576
mth .__doc__ = getattr (
573
577
getattr (AbstractFileSystem , smethod , None ), "__doc__" , ""
574
578
)
579
+
580
+
581
+ class FSSpecCoroutineCancel (Exception ):
582
+ pass
583
+
584
+
585
+ def _dump_running_tasks (
586
+ printout = True , cancel = True , exc = FSSpecCoroutineCancel , with_task = False
587
+ ):
588
+ import traceback
589
+
590
+ if PY36 :
591
+ raise NotImplementedError ("Do not call this on Py 3.6" )
592
+
593
+ tasks = [t for t in asyncio .tasks .all_tasks (loop [0 ]) if not t .done ()]
594
+ if printout :
595
+ [task .print_stack () for task in tasks ]
596
+ out = [
597
+ {
598
+ "locals" : task ._coro .cr_frame .f_locals ,
599
+ "file" : task ._coro .cr_frame .f_code .co_filename ,
600
+ "firstline" : task ._coro .cr_frame .f_code .co_firstlineno ,
601
+ "linelo" : task ._coro .cr_frame .f_lineno ,
602
+ "stack" : traceback .format_stack (task ._coro .cr_frame ),
603
+ "task" : task if with_task else None ,
604
+ }
605
+ for task in tasks
606
+ ]
607
+ if cancel :
608
+ for t in tasks :
609
+ cbs = t ._callbacks
610
+ t .cancel ()
611
+ asyncio .futures .Future .set_exception (t , exc )
612
+ asyncio .futures .Future .cancel (t )
613
+ [cb [0 ](t ) for cb in cbs ] # cancels any dependent concurrent.futures
614
+ try :
615
+ t ._coro .throw (exc ) # exits coro, unless explicitly handled
616
+ except exc :
617
+ pass
618
+ return out
0 commit comments