Allow modules to schedule delayed background calls. (#15993)

* Add a module API function to provide `call_later`

* Newsfile

Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>

* Add comments

* Update version number

---------

Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>
This commit is contained in:
reivilibre 2023-08-08 10:53:49 +00:00 committed by GitHub
parent f3dc6dc19f
commit a476d5048b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 0 deletions

1
changelog.d/15993.misc Normal file
View File

@ -0,0 +1 @@
Allow modules to schedule delayed background calls.

View File

@ -34,6 +34,7 @@ import jinja2
from typing_extensions import ParamSpec from typing_extensions import ParamSpec
from twisted.internet import defer from twisted.internet import defer
from twisted.internet.interfaces import IDelayedCall
from twisted.web.resource import Resource from twisted.web.resource import Resource
from synapse.api import errors from synapse.api import errors
@ -1242,6 +1243,46 @@ class ModuleApi:
""" """
return self._hs.config.worker.run_background_tasks return self._hs.config.worker.run_background_tasks
def delayed_background_call(
self,
msec: float,
f: Callable,
*args: object,
desc: Optional[str] = None,
**kwargs: object,
) -> IDelayedCall:
"""Wraps a function as a background process and calls it in a given number of milliseconds.
The scheduled call is not persistent: if the current Synapse instance is
restarted before the call is made, the call will not be made.
Added in Synapse v1.90.0.
Args:
msec: How long to wait before calling, in milliseconds.
f: The function to call once. f can be either synchronous or
asynchronous, and must follow Synapse's logcontext rules.
More info about logcontexts is available at
https://matrix-org.github.io/synapse/latest/log_contexts.html
*args: Positional arguments to pass to function.
desc: The background task's description. Default to the function's name.
**kwargs: Keyword arguments to pass to function.
Returns:
IDelayedCall handle from twisted, which allows to cancel the delayed call if desired.
"""
if desc is None:
desc = f.__name__
return self._clock.call_later(
# convert ms to seconds as needed by call_later.
msec * 0.001,
run_as_background_process,
desc,
lambda: maybe_awaitable(f(*args, **kwargs)),
)
async def sleep(self, seconds: float) -> None: async def sleep(self, seconds: float) -> None:
"""Sleeps for the given number of seconds. """Sleeps for the given number of seconds.