Repeating Work

The basic form of a repeating function in Fritter has a signature that lookslike this:

defwork(steps:StepsT,scheduled:SomeScheduledCall)->None:...

The parameters are, respectively, thesteps thatwork should perform inthis invocation, and an object with a.cancel() method that will stop thenext iteration from occurring.

Sometimes, real time moves more quickly than your code can keep up. Perhapsyour code is slow, or you need to wait on an external system; whatever thereason, if if you’ve got a timer that is supposed to repeat every N seconds,eventually, you’ll see a repetition happen after 2N seconds, or more. At thatpoint, any logic needs to catch up.

steps can reflect this multiple ways, depending on the type of recurrenceyou are using. Recurrence rules

And of course you need to be able to stop the repetition, and thestopper’s.cancel() method is there to help you do that.

Let’s get set up with our imports.

fromfritter.boundariesimportSomeScheduledCallfromfritter.drivers.sleepimportSleepDriverfromfritter.repeatimportrepeatedlyfromfritter.repeat.rules.secondsimportEverySecondfromfritter.schedulerimportschedulerFromDriver

To demonstrate some repetitions, let’s set up aSleepDriver. The sleep driver will run stuff in realtime with no event loop; just blocking while work is still scheduled with thedriver.

driver=SleepDriver()start=driver.now()

Let’s define some repeating work that runs for a finite number of times; itshould stop after 2 seconds, by cancelling its stopper:

defwork(steps:int,scheduled:SomeScheduledCall)->None:elapsed=driver.now()-startprint(f"took{steps} steps at{elapsed:0.2f}")ifelapsed>=2.0:scheduled.cancel()

Next, we’ll userepeatedly with ascheduler wrapped around our driver, and then block the driver:

repeatedly(schedulerFromDriver(driver),work,EverySecond(0.05))steps=driver.block()print(f"took{steps} steps, then stopped")

This will print out a bunch of steps, taking 2 wall-clock seconds to run, andthe output should look something like this:

took1stepsat0.00took1stepsat0.05took1stepsat0.11...took1stepsat1.95took1stepsat2.01took40steps,thenstopped
fromasyncioimportrunfromfritter.boundariesimport(Cancellable,PhysicalScheduler,)fromfritter.drivers.asyncioimportAsyncioAsyncDriver,AsyncioTimeDriverfromfritter.repeatimportAsyncfromfritter.repeat.rules.secondsimportEverySecondfromfritter.schedulerimportschedulerFromDriver
fromasyncioimportrunfromfritter.boundariesimport(Cancellable,PhysicalScheduler,)fromfritter.drivers.asyncioimportAsyncioAsyncDriver,AsyncioTimeDriverfromfritter.repeatimportAsyncfromfritter.repeat.rules.secondsimportEverySecondfromfritter.schedulerimportschedulerFromDriver