|
11 | 11 | from common_library.async_tools import cancel_wait_task |
12 | 12 | from models_library.api_schemas_long_running_tasks.base import TaskProgress |
13 | 13 | from pydantic import NonNegativeFloat, PositiveFloat |
| 14 | +from servicelib.utils import limited_gather |
14 | 15 | from settings_library.redis import RedisDatabase, RedisSettings |
15 | 16 | from tenacity import ( |
16 | 17 | AsyncRetrying, |
|
50 | 51 | _STATUS_UPDATE_CHECK_INTERNAL: Final[datetime.timedelta] = datetime.timedelta(seconds=1) |
51 | 52 | _MAX_EXCLUSIVE_TASK_CANCEL_TIMEOUT: Final[NonNegativeFloat] = 5 |
52 | 53 | _TASK_REMOVAL_MAX_WAIT: Final[NonNegativeFloat] = 60 |
| 54 | +_PARALLEL_TASKS_CANCELLATION: Final[int] = 5 |
53 | 55 |
|
54 | 56 | AllowedErrrors: TypeAlias = tuple[type[BaseException], ...] |
55 | 57 |
|
@@ -205,34 +207,40 @@ async def setup(self) -> None: |
205 | 207 | await self._started_event_task_tasks_monitor.wait() |
206 | 208 |
|
207 | 209 | async def teardown(self) -> None: |
208 | | - # ensure all created tasks are cancelled |
209 | | - for tracked_task in await self._tasks_data.list_tasks_data(): |
210 | | - with suppress(TaskNotFoundError): |
211 | | - await self.remove_task( |
212 | | - tracked_task.task_id, |
213 | | - tracked_task.task_context, |
214 | | - wait_for_removal=True, |
215 | | - ) |
| 210 | + # stop cancelled_tasks_removal |
| 211 | + if self._task_cancelled_tasks_removal: |
| 212 | + await cancel_wait_task(self._task_cancelled_tasks_removal) |
216 | 213 |
|
217 | | - for task in self._created_tasks.values(): |
218 | | - _logger.warning( |
219 | | - "Task %s was not completed before shutdown, cancelling it", |
220 | | - task.get_name(), |
| 214 | + # stopping only tasks that are handled by this manager |
| 215 | + # otherwise it will cancel long running tasks that were running in diffierent processes |
| 216 | + async def _remove_local_task(task_data: TaskData) -> None: |
| 217 | + await self.remove_task( |
| 218 | + task_data.task_id, |
| 219 | + task_data.task_context, |
| 220 | + wait_for_removal=False, |
221 | 221 | ) |
222 | | - await cancel_wait_task(task) |
| 222 | + await self._attempt_to_remove_local_task(task_data.task_id) |
223 | 223 |
|
224 | | - # stale_tasks_monitor |
| 224 | + tasks_to_remove = [] |
| 225 | + for task_id in self._created_tasks: |
| 226 | + tracked_task = await self._tasks_data.get_task_data(task_id) |
| 227 | + if tracked_task is None: |
| 228 | + continue |
| 229 | + |
| 230 | + tasks_to_remove.append(_remove_local_task(tracked_task)) |
| 231 | + |
| 232 | + await limited_gather( |
| 233 | + *tasks_to_remove, log=_logger, limit=_PARALLEL_TASKS_CANCELLATION |
| 234 | + ) |
| 235 | + |
| 236 | + # stop stale_tasks_monitor |
225 | 237 | if self._task_stale_tasks_monitor: |
226 | 238 | await cancel_wait_task( |
227 | 239 | self._task_stale_tasks_monitor, |
228 | 240 | max_delay=_MAX_EXCLUSIVE_TASK_CANCEL_TIMEOUT, |
229 | 241 | ) |
230 | 242 |
|
231 | | - # cancelled_tasks_removal |
232 | | - if self._task_cancelled_tasks_removal: |
233 | | - await cancel_wait_task(self._task_cancelled_tasks_removal) |
234 | | - |
235 | | - # tasks_monitor |
| 243 | + # stop tasks_monitor |
236 | 244 | if self._task_tasks_monitor: |
237 | 245 | await cancel_wait_task(self._task_tasks_monitor) |
238 | 246 |
|
|
0 commit comments