@@ -89,7 +89,7 @@ async def run(
89
89
"""
90
90
if self .is_running :
91
91
raise RuntimeError ("Cannot start the service while it's already running" )
92
- elif self .cancel_token . triggered :
92
+ elif self .is_cancelled :
93
93
raise RuntimeError ("Cannot restart a service that has already been cancelled" )
94
94
95
95
if finished_callback :
@@ -135,6 +135,7 @@ async def _run_task_wrapper() -> None:
135
135
pass
136
136
except Exception as e :
137
137
self .logger .warning ("Task %s finished unexpectedly: %s" , awaitable , e )
138
+ self .logger .warning ("Task failure traceback" , exc_info = True )
138
139
else :
139
140
self .logger .debug ("Task %s finished with no errors" , awaitable )
140
141
self ._tasks .add (asyncio .ensure_future (_run_task_wrapper ()))
@@ -158,7 +159,7 @@ async def _run_daemon_wrapper() -> None:
158
159
try :
159
160
await service .run ()
160
161
finally :
161
- if not self .cancel_token . triggered :
162
+ if not self .is_cancelled :
162
163
self .logger .debug (
163
164
"%s finished while we're still running, terminating as well" , service )
164
165
self .cancel_token .trigger ()
@@ -188,7 +189,7 @@ async def cleanup(self) -> None:
188
189
189
190
async def cancel (self ) -> None :
190
191
"""Trigger the CancelToken and wait for the cleaned_up event to be set."""
191
- if self .cancel_token . triggered :
192
+ if self .is_cancelled :
192
193
self .logger .warning ("Tried to cancel %s, but it was already cancelled" , self )
193
194
return
194
195
elif not self .is_running :
@@ -215,6 +216,14 @@ def _forcibly_cancel_all_tasks(self) -> None:
215
216
for task in self ._tasks :
216
217
task .cancel ()
217
218
219
+ @property
220
+ def is_cancelled (self ) -> bool :
221
+ return self .cancel_token .triggered
222
+
223
+ @property
224
+ def is_operational (self ) -> bool :
225
+ return self .events .started .is_set () and not self .cancel_token .triggered
226
+
218
227
@property
219
228
def is_running (self ) -> bool :
220
229
return self ._run_lock .locked ()
0 commit comments