...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package submission
16
17 import (
18 "context"
19 "fmt"
20 "sync"
21 "time"
22
23 "github.com/google/certificate-transparency-go/schedule"
24 "github.com/google/trillian/monitoring"
25 )
26
27 var (
28 logRefOnce sync.Once
29 logListLastRefresh monitoring.Gauge
30 )
31
32
33 func logRefInitMetrics(ctx context.Context, mf monitoring.MetricFactory) {
34 logListLastRefresh = mf.NewGauge("log_list_last_refresh", "Unix timestamp for last successful Log-list refresh")
35 }
36
37
38
39 type LogListManager struct {
40 Errors chan error
41 LLUpdates chan LogListData
42
43 llRefreshInterval time.Duration
44
45 llr LogListRefresher
46 latestLL *LogListData
47 previousLL *LogListData
48 mu sync.Mutex
49
50 mtf monitoring.MetricFactory
51 }
52
53
54 func NewLogListManager(llr LogListRefresher, mf monitoring.MetricFactory) *LogListManager {
55 if mf == nil {
56 mf = monitoring.InertMetricFactory{}
57 }
58 return &LogListManager{
59 Errors: make(chan error, 1),
60 LLUpdates: make(chan LogListData, 1),
61 llr: llr,
62 mtf: mf,
63 }
64 }
65
66
67
68
69 func (llm *LogListManager) Run(ctx context.Context, llRefresh time.Duration) {
70 llm.llRefreshInterval = llRefresh
71 logRefOnce.Do(func() { logRefInitMetrics(ctx, llm.mtf) })
72 go schedule.Every(ctx, llm.llRefreshInterval, llm.refreshLogListAndNotify)
73 }
74
75
76
77 func (llm *LogListManager) refreshLogListAndNotify(ctx context.Context) {
78 if lld, err := llm.RefreshLogList(ctx); err != nil {
79 llm.Errors <- err
80 } else if lld != nil {
81 llm.LLUpdates <- llm.ProduceClientLogList()
82 }
83 }
84
85
86 func (llm *LogListManager) GetTwoLatestLogLists() (*LogListData, *LogListData) {
87 llm.mu.Lock()
88 defer llm.mu.Unlock()
89 return llm.latestLL, llm.previousLL
90 }
91
92
93 func (llm *LogListManager) RefreshLogList(ctx context.Context) (*LogListData, error) {
94 if llm.llr == nil {
95 return nil, fmt.Errorf("the LogListManager has no LogListRefresher")
96 }
97 ll, err := llm.llr.Refresh()
98 if err != nil {
99 return nil, err
100 }
101 logListLastRefresh.Set(float64(time.Now().Unix()))
102 if ll == nil {
103
104 return nil, nil
105 }
106 llm.mu.Lock()
107 defer llm.mu.Unlock()
108 llm.previousLL = llm.latestLL
109 llm.latestLL = ll
110 return llm.latestLL, nil
111 }
112
113
114 func (llm *LogListManager) ProduceClientLogList() LogListData {
115
116 clientLL := *(llm.latestLL)
117 return clientLL
118 }
119
120
121 func (llm *LogListManager) Source() string {
122 return llm.llr.Source()
123 }
124
125
126 func (llm *LogListManager) LastJSON() []byte {
127 return llm.llr.LastJSON()
128 }
129
View as plain text