1. Create the project
Output
2. Write the actor
Replaceactors/reminders/main.py with:
Once, after a delay
runtime.schedule_after(seconds, handler, payload) runs handler once, seconds from now, with payload as its raw bytes. Here, remind schedules fire that way. fire is @callable_by(SELF), which means only the actor itself can call it, and a timer runs as the actor. decode="raw" hands it the payload as bytes.
schedule_after returns the timer’s id, and runtime.cancel_timer(timer_id) stops a timer that hasn’t run. That’s why remind keeps each id: so forget can cancel it.
Delays are in seconds, which you can write with MINUTE, HOUR, DAY and WEEK. They can reach up to about 30 days ahead, and longer ones are refused.
On a schedule
@every(period) makes a handler run every period seconds, once every.start starts it. every.start(self.check) starts the schedule, or restarts it if it is running, and the first run comes one full period later. every.stop(self.check) ends it.
Only the schedule runs the handler. A call from anyone, the owner included, is refused, so nobody can run it early. A run that raises undoes its own changes and keeps the schedule.
3. Test it
Replacetests/test_reminders.py with:
Output
chain.advance_block(n) moves time forward n blocks and runs every timer that comes due, where a block is the network’s unit of about one second.
4. Run it on your machine
Output
cowboy actor timers <actor> shows its timers.
Who pays, and when the money runs out
The actor pays for each run. If its balance can’t cover one, the timer is removed and the handler doesn’t run. That also ends an@every schedule, because each run sets the next one.
Scheduled runs come only from the actor’s balance, so keep it funded: cowboy actor fund adds money, and cowboy actor auto-topup refills it automatically (Deploy and operate). After a top-up, call start_checks again.