Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Document looping_call() functionality that will wait for the given function to finish before scheduling another #15772

Merged
merged 3 commits into from Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/15772.doc
@@ -0,0 +1 @@
Document `looping_call()` functionality that will wait for the given function to finish before scheduling another.
5 changes: 5 additions & 0 deletions synapse/util/__init__.py
Expand Up @@ -116,6 +116,11 @@ def looping_call(

Waits `msec` initially before calling `f` for the first time.

If the function given to `looping_call` returns an awaitable/deferred, the next
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.twistedmatrix.com/en/stable/api/twisted.internet.task.LoopingCall.html only mentions deferred but it looks like the source uses maybeDeferred which works with coroutines/awaitables (which makes this accurate)

twisted.internet.task.LoopingCall

If f returns a deferred, rescheduling will not take place until the deferred has fired.

def maybeDeferred(f, *args, **kwargs): (source)

Invoke a function that may or may not return a Deferred or coroutine.

Call the given function with the given arguments. Then:

  • If the returned object is a Deferred, return it.
  • If the returned object is a Failure, wrap it with fail and return it.
  • If the returned object is a types.CoroutineType, wrap it with Deferred.fromCoroutine and return it.
  • Otherwise, wrap it in succeed and return it.
  • If an exception is raised, convert it to a Failure, wrap it in fail, and then return it.

call isn't scheduled until after the returned awaitable has finished. We get
this functionality thanks to this function being a thin wrapper around
`twisted.internet.task.LoopingCall`.

Note that the function will be called with no logcontext, so if it is anything
other than trivial, you probably want to wrap it in run_as_background_process.

Expand Down