Loop Wrapper
LoopWrapper is telegrinder's event-loop orchestration utility. It is responsible for:
- scheduling background tasks
- running startup and shutdown hooks
- handling delayed and periodic tasks
- shutting down tasks safely
Telegrinder already uses a LoopWrapper internally, so in most bots you interact with it through bot.loop_wrapper.
Basic idea
In actual bot code you usually do not create and run a separate wrapper manually. Instead:
Singleton behavior
LoopWrapper is a singleton. The same shared wrapper is used across the application unless you explicitly rebind it to another event loop.
Useful properties:
lifespanfor startup and shutdown tasksloopfor the underlying event looptimefor loop timerunningto check whether the wrapper is activeshutting_downto check whether shutdown has started
Startup and shutdown hooks
The most common use is startup and shutdown registration:
In a bot:
Reference: examples/loop_wrapper.py
Adding tasks
add_task(...) schedules a task for the wrapper.
If the wrapper is not running yet:
- the task is queued
- it will start when the wrapper starts
If the wrapper is already running:
- the task is created immediately in the current loop
That makes it safe to prepare background work before bot.run_forever() as well as while the wrapper is already active.
Delayed and periodic tasks
LoopWrapper provides two decorators:
timer(...)for one-shot delayed executioninterval(...)for repeated execution
Example:
timer is executed once after the delay.
interval is re-scheduled after each run.
Delayed tasks expose .cancel() on the decorated function.
Running the wrapper manually
If you use LoopWrapper outside Telegrinder, call:
By default it closes the loop after shutdown. If you need to keep the loop open:
Usually you should not call run() yourself when the bot lifecycle is already managed by Telegrinder.
Shutdown
To stop the wrapper programmatically:
The wrapper also installs signal handlers where possible and performs safe cancellation of pending tasks during shutdown.
Working with an already running loop
If some other framework owns the event loop, LoopWrapper can attach itself to that running loop.
Current relevant methods are:
attach_to_running_loop()bind_event_loop(loop)create_task_group()
create_task_group() is especially useful when you want structured concurrent work integrated with the wrapper's loop handling.
Event-loop binding
If you need to explicitly bind a loop:
This replaces older documentation that referred to bind_loop(...) or event_loop; the current API uses bind_event_loop(...) and the loop property.
Practical guidance
Use LoopWrapper for:
- startup initialization
- graceful shutdown cleanup
- repeating polling or maintenance jobs
- delayed follow-up actions
- background coroutines that should live with the bot lifecycle
Do not use it as a replacement for persistent job scheduling or long-term workflow state. For those cases you still need external storage or a dedicated scheduler.