oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1package calendar
2
3import (
4 "context"
5 "errors"
6 "time"
7
8 "amadan.net/rastrillo/rastrillo/carlos"
9)
10
11func (s *scheduledWork) matches(remote remoteSchedule) bool {
12 if remote.NextAt <= 0 || remote.Kind != "once" || remote.Path != "/jobs/reminders" {
13 return false
14 }
15 occurrence := remote.DueAt
16 if occurrence == 0 {
17 occurrence = remote.NextAt
18 }
19 if occurrence != s.registeredAt.Unix() {
20 return false
21 }
22 return remote.NextAt == occurrence || (remote.Attempts > 0 && remote.NextAt <= s.now().Add(15*time.Minute).Unix())
23}
24
25func (s *scheduledWork) restore(parent context.Context, due time.Time) (bool, error) {
26 ctx, cancel := context.WithTimeout(parent, 2*time.Second)
27 err := s.capability(ctx)
28 cancel()
29 if errors.Is(err, carlos.ErrNotOnCarlos) && s.development {
30 return false, nil
31 }
32 if err != nil {
33 return false, err
34 }
35 ctx, cancel = context.WithTimeout(parent, 2*time.Second)
36 remote, err := s.armed(ctx)
37 cancel()
38 if err != nil {
39 return false, err
40 }
41 if due.IsZero() || remote.NextAt <= 0 || remote.Kind != "once" || remote.Path != "/jobs/reminders" {
42 return false, nil
43 }
44 occurrence := remote.DueAt
45 if occurrence == 0 {
46 occurrence = remote.NextAt
47 }
48 now := s.now()
49 if remote.NextAt != occurrence && (remote.Attempts <= 0 || remote.NextAt > now.Add(15*time.Minute).Unix()) {
50 return false, nil
51 }
52 if due.After(now) {
53 at := due
54 if latest := now.Add(carlos.MaxAhead - time.Minute); at.After(latest) {
55 at = latest
56 }
57 if occurrence != at.Unix() {
58 return false, nil
59 }
60 } else {
61 if occurrence < due.Unix() || remote.NextAt > now.Add(15*time.Minute).Unix() {
62 return false, nil
63 }
64 if remote.NextAt > now.Unix() {
65 s.notBefore = time.Unix(remote.NextAt, 0)
66 due = s.notBefore
67 }
68 }
69 s.known, s.force = true, false
70 s.registered, s.observed = due, due
71 s.registeredAt = time.Unix(occurrence, 0)
72 s.checked = now
73 return true, nil
74}
75
76func (s *scheduledWork) probe() time.Time {
77 if !s.mu.TryLock() {
78 return time.Now()
79 }
80 defer s.mu.Unlock()
81 ctx, cancel := context.WithTimeout(s.ctx, 4*time.Second)
82 defer cancel()
83 due, err := s.synchronizeLocked(ctx, false, true)
84 if err != nil {
85 s.request()
86 return s.now()
87 }
88 return due
89}
90