-
Notifications
You must be signed in to change notification settings - Fork 6
/
source.go
123 lines (93 loc) · 2.91 KB
/
source.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package server
import (
"sync"
"time"
"github.com/doomsday-project/doomsday/server/logger"
"github.com/doomsday-project/doomsday/storage"
)
type Source struct {
Core *Core
Interval time.Duration
lock sync.RWMutex
authTTL time.Duration
refreshStatus RunInfo
authStatus RunInfo
authMetadata interface{}
}
type RunInfo struct {
LastRun RunTiming
LastSuccess RunTiming
LastErr error
}
type RunTiming struct {
StartedAt time.Time
FinishedAt time.Time
}
func (s *Source) Refresh(global *Cache, log *logger.Logger) {
log.WriteF("Running populate of `%s'", s.Core.Name)
old := s.Core.Cache()
if old == nil {
old = NewCache()
}
s.lock.Lock()
s.refreshStatus.LastRun = RunTiming{StartedAt: time.Now()}
s.lock.Unlock()
results, err := s.Core.Populate()
s.lock.Lock()
defer s.lock.Unlock()
s.refreshStatus.LastRun.FinishedAt = time.Now()
if err != nil {
log.WriteF("Error populating info from backend `%s': %s", s.Core.Name, err)
s.refreshStatus.LastErr = err
return
}
s.refreshStatus.LastErr = nil
s.refreshStatus.LastSuccess = s.refreshStatus.LastRun
global.ApplyDiff(old, s.Core.Cache())
log.WriteF("Finished populate of `%s' after %s. %d/%d paths searched. %d certs found", s.Core.Name, time.Since(s.refreshStatus.LastRun.StartedAt), results.NumSuccess, results.NumPaths, results.NumCerts)
}
func (s *Source) Auth(log *logger.Logger) {
log.WriteF("Starting authentication for `%s'", s.Core.Name)
s.lock.Lock()
s.authStatus.LastRun = RunTiming{StartedAt: time.Now()}
s.lock.Unlock()
ttl, metadata, err := s.Core.Backend.Authenticate(s.authMetadata)
s.lock.Lock()
defer s.lock.Unlock()
s.authStatus.LastRun.FinishedAt = time.Now()
if err != nil {
log.WriteF("Failed auth for `%s' after %s: %s", s.Core.Name, time.Since(s.authStatus.LastRun.StartedAt), err)
s.authStatus.LastErr = err
return
}
s.authStatus.LastErr = nil
s.authStatus.LastSuccess = s.authStatus.LastRun
s.authTTL = ttl
s.authMetadata = metadata
log.WriteF("Finished auth for `%s' after %s", s.Core.Name, time.Since(s.authStatus.LastRun.StartedAt))
}
//CalcNextAuth returns the time of the next authentication to attempt.
// The second return value is true if this should never be scheduled again
func (s *Source) CalcNextAuth() (time.Time, bool) {
s.lock.RLock()
defer s.lock.RUnlock()
if s.authTTL == storage.TTLInfinite {
return time.Time{}, true
}
expiryTime := s.authStatus.LastSuccess.StartedAt.Add(s.authTTL)
authInterval := expiryTime.Sub(s.authStatus.LastRun.FinishedAt) / 2
if authInterval < MinAuthInterval {
authInterval = MinAuthInterval
}
nextAuth := s.authStatus.LastRun.FinishedAt.Add(authInterval)
if nextAuth.After(expiryTime) {
nextAuth = s.authStatus.LastRun.FinishedAt.Add(ExpiredRetryInterval)
}
return nextAuth, false
}
func (s *Source) CalcNextRefresh() time.Time {
s.lock.RLock()
ret := s.refreshStatus.LastRun.FinishedAt.Add(s.Interval)
s.lock.RUnlock()
return ret
}