30
30
Overflow_In = Any
31
31
32
32
33
+ Threads : set ['Thread' ] = set ()
33
34
class Thread (threading .Thread ):
34
35
"""
35
36
Wraps python's `threading.Thread` class
@@ -108,6 +109,9 @@ def _wrap_target(self, target: Callable[..., Data_Out]) -> Callable[..., Data_Ou
108
109
def wrapper (* args : Any , ** kwargs : Any ) -> Any :
109
110
self .status = 'Running'
110
111
112
+ global Threads
113
+ Threads .add (self )
114
+
111
115
try :
112
116
self .returned_value = target (* args , ** kwargs )
113
117
except Exception as e :
@@ -118,6 +122,7 @@ def wrapper(*args: Any, **kwargs: Any) -> Any:
118
122
119
123
self .status = 'Invoking hooks'
120
124
self ._invoke_hooks ()
125
+ Threads .remove (self )
121
126
self .status = 'Completed'
122
127
return wrapper
123
128
@@ -156,7 +161,7 @@ def global_trace(self, frame, event: str, arg) -> Optional[Callable]:
156
161
157
162
def local_trace (self , frame , event : str , arg ):
158
163
if self .status == 'Kill Scheduled' and event == 'line' :
159
- print ('KILLED ident:%s' % self .ident )
164
+ print ('KILLED ident: %s' % self .ident )
160
165
self .status = 'Killed'
161
166
raise SystemExit ()
162
167
return self .local_trace
@@ -524,9 +529,14 @@ def service_shutdown(signum, frame):
524
529
print ('\n Caught signal %d' % signum )
525
530
print ('Gracefully killing active threads' )
526
531
527
- for thread in threading . enumerate () :
532
+ for thread in Threads :
528
533
if isinstance (thread , Thread ):
529
- thread .kill ()
534
+ try :
535
+ thread .kill ()
536
+ except (exceptions .ThreadNotRunningError , exceptions .ThreadNotInitializedError ):
537
+ pass
538
+ except Exception as e :
539
+ print ('Failed to kill ident: %d' % thread .ident or 0 )
530
540
sys .exit (0 )
531
541
532
542
0 commit comments