+// deliver logs the message of each due schedule in l, in due order, as a work
+// message of scheduleSource, and wakes the loop once with all of them. A
+// schedule ends its run with Done after its message is durable in the log. A
+// crash between the two makes the run repeat once.
+func (s *Schedules) deliver(ctx context.Context, l *TurnLoop) error {
+ now := s.clock()
+ var turns []Message
+ for _, schedule := range s.Due(now) {
+ message, err := l.Work(scheduleSource, schedule.Message(now), "")
+ if err != nil {
+ return fmt.Errorf("log a schedule: %w", err)
+ }
+
+ // A stop of the daemon during the flush is no failure: the
+ // schedule stays due and runs at the next start.
+ err = l.Flush(ctx)
+ if ctx.Err() != nil {
+ return nil
+ }
+
+ if err != nil {
+ return fmt.Errorf("log a schedule: %w", err)
+ }
+
+ err = s.Done(schedule, now)
+ if err != nil {
+ return err
+ }
+
+ turns = append(turns, message)
+ }
+
+ l.Wake(turns...)
+
+ return nil
+}
+