Skip to content

feat(loop): add optional overlap support to allow concurrent loop executions #2765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

Lumabots
Copy link

@Lumabots Lumabots commented Apr 18, 2025

…xecutions

Added a new overlap parameter to the loop decorator and Loop class to control whether loop iterations can run concurrently. When set to True, the next iteration will not wait for the previous one to finish, allowing overlapping executions—useful for long-running tasks that should not delay subsequent runs. Defaults to False to preserve current behavior.

Summary

Information

  • This PR fixes an issue.
  • This PR adds something new (e.g. new method or parameters).
  • This PR is a breaking change (e.g. methods or parameters removed/renamed).
  • This PR is not a code change (e.g. documentation, README, typehinting,
    examples, ...).

Checklist

  • I have searched the open pull requests for duplicates.
  • If code changes were made then they have been tested.
    • I have updated the documentation to reflect the changes.
  • If type: ignore comments were used, a comment is also left explaining why.
  • I have updated the changelog to include these changes.

…xecutions

Added a new overlap parameter to the loop decorator and Loop class to control whether loop iterations can run concurrently. When set to True, the next iteration will not wait for the previous one to finish, allowing overlapping executions—useful for long-running tasks that should not delay subsequent runs. Defaults to False to preserve current behavior.

Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
pre-commit-ci bot and others added 4 commits April 18, 2025 13:46
Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
@Lumabots Lumabots changed the title 🆕 feat(loop): add optional overlap support to allow concurrent loop e… feat(loop): add optional overlap support to allow concurrent loop executions Apr 18, 2025
@Paillat-dev
Copy link
Contributor

Testing needed, also shouldn't a reference to the task be stored somewhere? An easy way is to have a set storing them and binding the task completion to set.remove

…t: 'overlap'

Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
@Lumabots
Copy link
Author

i did test it and everything seems to works fine, but i dont really know why we would store it since the old self.coro was not stored either

@Lumabots
Copy link
Author

well the cancel does not end the create tasks, i'll fix that

Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
Exception in callback Future.set_result(True)
handle: <TimerHandle when=203424.768941542 Future.set_result(True)>
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/asyncio/events.py", line 84, in _run
    self._context.run(self._callback, *self._args)
asyncio.exceptions.InvalidStateError: invalid state


Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com>
@Lumabots
Copy link
Author

ready for review, did lot of testing and everything seems to works.
tested:
all with overlap true and false

  • after loop
  • before loop
  • cancel
  • stop

@Icebluewolf
Copy link
Contributor

Icebluewolf commented Apr 18, 2025

Could you add documentation to stop and cancel to say how they behave differently.
Also can you test restart.
How does get_task, current_interation, and next_interation behave?

Overall good addition, but I think it needs a bit more polishing.

@Lumabots
Copy link
Author

So:
current_iteration:
Still works the same — just gives you the current loop count, nothing fancy.

next_iteration:
This one’s a bit more precise now. Instead of waiting for the task to finish, it always schedules the next run based on the original interval. So if it's set to run every 30s, it'll always be 30s from the start of the current iteration, not after it finishes. Helps keep the timing tight.

get_task():
Returns the same internal task each time. Nothing changed here. Even with overlap=True, it behaves just like before.

There’s no change in behavior for stop() and cancel() — so nothing to add doc-wise unless we want to clarify their purpose in general.

For the restart it does cancel the tasks and restart perfectly
here some debug log (the debug test restart the loop) there is a 30s delay between each loop and inside the loop an asyncio.sleep(45)
Screenshot 2025-04-18 at 21 07 34

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants