comparison libervia/frontends/tools/aio.py @ 4127:5fc26a6ef113

frontends (tools) new `aio` module for tools regarding asyncio: A first method lets run an async method from blocking code. rel 424
author Goffi <goffi@goffi.org>
date Tue, 03 Oct 2023 16:27:51 +0200
parents
children 5de6f3595380
comparison
equal deleted inserted replaced
4126:45e3bb8607d8 4127:5fc26a6ef113
1 #!/usr/bin/env python3
2
3 # Libervia AsyncIO helper methods
4 # Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org)
5
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Affero General Public License for more details.
15
16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 import asyncio
20 from typing import Any, Coroutine
21
22 from libervia.backend.core import log as logging
23
24 log = logging.getLogger(__name__)
25 background_tasks = set()
26
27
28 def _on_task_done(task: asyncio.Future) -> None:
29 """Callback function to execute when a task is done.
30
31 @param task: The completed task.
32 Note: The function removes the task from the tracking set and logs any exceptions
33 that might have occurred.
34 """
35 background_tasks.discard(task)
36 e = task.exception()
37 if e is not None:
38 exc_info = (type(e), e, e.__traceback__)
39 log.error("Task failed:", exc_info=exc_info)
40
41
42 def run_async(async_method: Coroutine | asyncio.Future) -> None:
43 """Schedules and tracks an asynchronous method.
44
45 @param async_method: The method to be scheduled for execution.
46 Note: The function keeps a strong reference to the task to prevent it from being
47 garbage-collected. In case of task failure, logs the error.
48 cf. https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task
49 """
50 if isinstance(async_method, asyncio.Future):
51 task = asyncio.ensure_future(async_method)
52 else:
53 task = asyncio.create_task(async_method)
54
55 background_tasks.add(task)
56 task.add_done_callback(_on_task_done)