This repository has been archived by the owner on Feb 25, 2023. It is now read-only.
forked from katzenpost/server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
periodic.go
79 lines (66 loc) · 2.25 KB
/
periodic.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
// periodic.go - Katzenpost server periodic timer.
// Copyright (C) 2017 Yawning Angel.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package server
import (
"time"
"github.com/katzenpost/core/worker"
)
type periodicTimer struct {
worker.Worker
s *Server
}
func (t *periodicTimer) worker() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
lastCallbackTime := time.Now()
for {
select {
case <-t.HaltCh():
return
case <-ticker.C:
}
// Do periodic housekeeping tasks at a rate of approximately 1 Hz.
//
// Most of these calls can be scheduled much more infrequently, but
// the no-op case is cheap enough that it probably doesn't matter.
//
// WARNING: None of the operations done here should block. If there's
// a need to do anything that's long lived, then it MUST be done async
// in a go routine.
// Ensure civil time sanity.
//
// TODO: Not sure what to do when the clock jumps around, it probably
// screws with epoch timing and PKI interactions, but everything
// should keep working, for varying amounts of "working".
now := time.Now()
deltaT := now.Sub(lastCallbackTime)
if deltaT < 0 {
t.s.log.Warningf("Civil time jumped backwards: %v", deltaT)
} else if deltaT > 2*time.Second {
t.s.log.Warningf("Civil time jumped forward: %v", deltaT)
}
// TODO: Figure out what needs to be triggered from the top level
// server instead of from timers belonging to a sub component.
// Stash the time we got unblocked as the last callback time.
lastCallbackTime = now
}
}
func newPeriodicTimer(s *Server) *periodicTimer {
t := new(periodicTimer)
t.s = s
t.Go(t.worker)
return t
}