Mercurial > libervia-backend
annotate libervia/frontends/tools/aio.py @ 4156:2729d424dee7
plugin XEP-0359: use same ID as <message> for `origin_id`:
even if the XEP doesn't specify if Message ID must be the same as `origin_id`, using a
different one makes little sense, and is leading to bugs in other implementation (e.g.
Movim using the wrong ID for reactions).
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 22 Nov 2023 15:05:41 +0100 |
parents | 5de6f3595380 |
children | d01b8d002619 |
rev | line source |
---|---|
4127
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1 #!/usr/bin/env python3 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
2 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
3 # Libervia AsyncIO helper methods |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
4 # Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
5 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # (at your option) any later version. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
19 import asyncio |
4138
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
20 from typing import Any, Awaitable, Callable, Coroutine |
4127
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
22 from libervia.backend.core import log as logging |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
23 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
24 log = logging.getLogger(__name__) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
25 background_tasks = set() |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
26 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
27 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
28 def _on_task_done(task: asyncio.Future) -> None: |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
29 """Callback function to execute when a task is done. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
30 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 @param task: The completed task. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
32 Note: The function removes the task from the tracking set and logs any exceptions |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
33 that might have occurred. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
34 """ |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
35 background_tasks.discard(task) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
36 e = task.exception() |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 if e is not None: |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 exc_info = (type(e), e, e.__traceback__) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 log.error("Task failed:", exc_info=exc_info) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 def run_async(async_method: Coroutine | asyncio.Future) -> None: |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 """Schedules and tracks an asynchronous method. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
44 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
45 @param async_method: The method to be scheduled for execution. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
46 Note: The function keeps a strong reference to the task to prevent it from being |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
47 garbage-collected. In case of task failure, logs the error. |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 cf. https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 """ |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
50 if isinstance(async_method, asyncio.Future): |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 task = asyncio.ensure_future(async_method) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 else: |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 task = asyncio.create_task(async_method) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
54 |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
55 background_tasks.add(task) |
5fc26a6ef113
frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
56 task.add_done_callback(_on_task_done) |
4138
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
57 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
58 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
59 def run_with_args( |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
60 async_method: Callable[..., Coroutine[Any, Any, Any]], *args: Any, **kwargs: Any |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
61 ) -> None: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
62 """Schedules and tracks an asynchronous method with arguments. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
63 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
64 This function wraps the provided asynchronous method with its arguments |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
65 and then schedules it for execution. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
66 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
67 @param async_method: The asynchronous method to be scheduled. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
68 @param args: Positional arguments to pass to the async_method. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
69 @param kwargs: Keyword arguments to pass to the async_method. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
70 """ |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
71 run_async(async_method(*args, **kwargs)) |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
72 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
73 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
74 def run_from_thread( |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
75 async_method: Coroutine | asyncio.Future, |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
76 *args, |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
77 loop: asyncio.AbstractEventLoop | None = None, |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
78 **kwargs, |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
79 ) -> None: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
80 """Schedules an asynchronous method from another thread. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
81 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
82 @param async_method: The method to be scheduled for execution. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
83 """ |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
84 if loop is None: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
85 loop = asyncio.get_event_loop() |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
86 assert loop is not None |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
87 loop.call_soon_threadsafe(run_with_args, async_method, *args, **kwargs) |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
88 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
89 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
90 def maybe_async(result: Any | Awaitable[Any]) -> Awaitable[Any]: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
91 """ |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
92 Convert the provided result into an awaitable. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
93 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
94 @param result: the result of a function or coroutine call |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
95 @return: an awaitable object which can be awaited to get the result |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
96 """ |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
97 if asyncio.iscoroutine(result): |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
98 return result |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
99 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
100 future = asyncio.Future() |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
101 future.set_result(result) |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
102 return future |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
103 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
104 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
105 def install_glib_asyncio_iteration(): |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
106 """Import and install GLib context iteration inside our asyncio event loop. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
107 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
108 This is used as soon as GLib is used (like GStreamer). |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
109 Inspired from Kivy's install_gobject_iteration (in ``kivy.support``), thanks to Kivy's |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
110 team. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
111 """ |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
112 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
113 import asyncio |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
114 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
115 try: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
116 from gi.repository import GLib |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
117 except ImportError: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
118 raise ImportError("GLib could not be imported. Ensure it's installed.") |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
119 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
120 if hasattr(GLib, "_glib_already_installed"): |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
121 # already installed, don't do it twice. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
122 return |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
123 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
124 GLib._glib_already_installed = True |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
125 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
126 loop = asyncio.get_event_loop() |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
127 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
128 # Create a GLib MainContext and make it the default |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
129 glib_context = GLib.MainContext.default() |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
130 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
131 # Function to iterate over the GLib main context |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
132 def _glib_iteration(): |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
133 # We need to loop over the context to prevent lag |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
134 iteration_count = 0 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
135 while glib_context.pending() and iteration_count < 20: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
136 glib_context.iteration(False) |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
137 iteration_count += 1 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
138 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
139 # If no work was done in the GLib loop, add a short delay before |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
140 # scheduling the next iteration, to prevent spinning and high CPU usage. |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
141 if iteration_count == 0: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
142 loop.call_later(0.01, _glib_iteration) |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
143 else: |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
144 # Schedule ourselves to run again on the next asyncio loop iteration |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
145 loop.call_soon(_glib_iteration) |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
146 |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
147 # Kick off the GLib iteration |
5de6f3595380
frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents:
4127
diff
changeset
|
148 loop.call_soon(_glib_iteration) |