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 all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/15772.doc
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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

@MadLittleMods MadLittleMods Jun 12, 2023

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