/
detect.go
105 lines (90 loc) · 2.71 KB
/
detect.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
package main
import (
"net/http"
"os"
"os/signal"
"syscall"
"time"
"goa.design/clue/log"
"douglasthrift.net/presence"
"douglasthrift.net/presence/ifttt"
"douglasthrift.net/presence/neighbors"
)
type (
Detect struct {
Iterations uint `help:"Only detect for N iterations." placeholder:"N" short:"i"`
}
)
func (d *Detect) Run(cli *CLI) error {
ctx := cli.Context()
config, err := presence.ParseConfigWithContext(ctx, cli.Config, wNet)
if err != nil {
log.Fatal(ctx, err, log.KV{K: "msg", V: "error parsing config"}, log.KV{K: "config", V: cli.Config})
}
arp, err := neighbors.NewARP(config.PingCount)
if err != nil {
log.Fatal(ctx, err, log.KV{K: "msg", V: "error finding dependencies"})
}
client, err := ifttt.NewClient(http.DefaultClient, config.IFTTT.BaseURL, config.IFTTT.Key, config.IFTTT.Events.Present, config.IFTTT.Events.Absent, cli.Debug)
if err != nil {
log.Fatal(ctx, err, log.KV{K: "msg", V: "error creating IFTTT client"})
}
var (
detector = presence.NewDetector(config, arp, client)
ticker = time.NewTicker(config.Interval)
stop = make(chan os.Signal, 1)
reload = make(chan os.Signal, 1)
i uint
)
err = detector.Detect(ctx)
if err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "error detecting presence"})
}
if d.Iterations != 0 {
i++
if i >= d.Iterations {
ticker.Stop()
return nil
}
}
signal.Ignore(syscall.SIGHUP)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
signal.Notify(reload, syscall.SIGUSR1)
for {
select {
case <-ticker.C:
err = detector.Detect(ctx)
if err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "error detecting presence"})
}
if d.Iterations != 0 {
i++
if i >= d.Iterations {
ticker.Stop()
return nil
}
}
case s := <-stop:
log.Print(ctx, log.Fields{"msg": "received stop signal"}, log.Fields{"signal": s})
ticker.Stop()
return nil
case s := <-reload:
log.Print(ctx, log.Fields{"msg": "received reload signal"}, log.Fields{"signal": s})
config, err = presence.ParseConfigWithContext(ctx, cli.Config, wNet)
if err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "error parsing config"}, log.KV{K: "config", V: cli.Config})
} else if client, err = ifttt.NewClient(http.DefaultClient, config.IFTTT.BaseURL, config.IFTTT.Key, config.IFTTT.Events.Present, config.IFTTT.Events.Absent, cli.Debug); err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "error creating IFTTT client"})
} else {
arp.Count(config.PingCount)
detector.Config(config)
detector.Client(client)
err = detector.Detect(ctx)
if err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "error detecting presence"})
}
ticker.Reset(config.Interval)
}
}
}
}