carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package schedule
2
3import (
4 "context"
5 "errors"
6
7 "github.com/carlosframework/platform/internal/hostwrite"
8 "github.com/carlosframework/platform/internal/registry"
9)
10
11var errTimerHost = errors.New("schedule: selected timer host differs")
12
13type SelectedTimers struct {
14 Store TimerStore
15 Work hostwrite.Work
16 Context context.Context
17 Host string
18}
19
20func (s SelectedTimers) write(host string, fn func() error) error {
21 if s.Store == nil || s.Work == nil || s.Context == nil {
22 return hostwrite.ErrUnavailable
23 }
24 if host != s.Host {
25 return errTimerHost
26 }
27 return s.Work.With(s.Context, hostwrite.Identity{}, fn)
28}
29func (s SelectedTimers) UpsertTimer(t registry.Timer) error {
30 t.Registration = ""
31 if handled, err := s.mutate(t, false); handled {
32 return err
33 }
34 return s.write(t.Host, func() error { return s.Store.UpsertTimer(t) })
35}
36func (s SelectedTimers) DeleteTimer(host, name string) error {
37 if handled, err := s.mutate(registry.Timer{Host: host, Name: name}, true); handled {
38 return err
39 }
40 return s.write(host, func() error { return s.Store.DeleteTimer(host, name) })
41}
42func (s SelectedTimers) GetTimer(host, name string) (*registry.Timer, error) {
43 if s.Store == nil {
44 return nil, hostwrite.ErrUnavailable
45 }
46 if host != s.Host {
47 return nil, errTimerHost
48 }
49 return s.Store.GetTimer(host, name)
50}
51func (s SelectedTimers) TimersFor(host string) ([]registry.Timer, error) {
52 if s.Store == nil {
53 return nil, hostwrite.ErrUnavailable
54 }
55 if host != s.Host {
56 return nil, errTimerHost
57 }
58 return s.Store.TimersFor(host)
59}
60func (s SelectedTimers) CountTimers(host, kind string) (int, error) {
61 if s.Store == nil {
62 return 0, hostwrite.ErrUnavailable
63 }
64 if host != s.Host {
65 return 0, errTimerHost
66 }
67 return s.Store.CountTimers(host, kind)
68}
69
70var _ TimerStore = SelectedTimers{}
71
72// ReplaceTimers imports a landing snapshot without changing registrations.
73// Its Work must have been selected as held-timers for the owning landing op.
74func (s SelectedTimers) ReplaceTimers(host string, rows []registry.Timer) error {
75 replacement, ok := s.Store.(interface {
76 ReplaceTimers(string, []registry.Timer) error
77 })
78 if !ok {
79 return hostwrite.ErrUnavailable
80 }
81 copyRows := append([]registry.Timer(nil), rows...)
82 for _, row := range copyRows {
83 if row.Host != host {
84 return errTimerHost
85 }
86 }
87 if _, ok := s.Work.(timerMutator); ok {
88 seen := map[string]bool{}
89 for _, row := range copyRows {
90 if row.Registration == "" || seen[row.Name] {
91 return registry.ErrClaimOwnership
92 }
93 seen[row.Name] = true
94 }
95 old, err := s.TimersFor(host)
96 if err != nil {
97 return err
98 }
99 keep := map[string]bool{}
100 for _, row := range copyRows {
101 keep[row.Name] = true
102 if _, err := s.mutate(row, false); err != nil {
103 return err
104 }
105 }
106 for _, row := range old {
107 if !keep[row.Name] {
108 if err := s.DeleteTimer(host, row.Name); err != nil {
109 return err
110 }
111 }
112 }
113 return nil
114 }
115 return s.write(host, func() error { return replacement.ReplaceTimers(host, copyRows) })
116}
117