From cbe2577aa9ce138bd8f134932dd92f1a9896a625 Mon Sep 17 00:00:00 2001 From: Julian Kornberger Date: Sat, 8 Oct 2016 10:50:41 +0200 Subject: [PATCH] Expire nodes after n days of inactivity closes #4 --- config_example.yml | 12 +++++++-- jsontime/jsontime.go | 6 ++++- models/config.go | 3 ++- models/nodes.go | 60 +++++++++++++++++++++++++++++++------------- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/config_example.yml b/config_example.yml index b28551c..2aae894 100644 --- a/config_example.yml +++ b/config_example.yml @@ -2,7 +2,9 @@ respondd: enable: true interface: eth0 - collectinterval: 15 + + # Collected data every n seconds + collectinterval: 60 webserver: enable: false port: 8080 @@ -16,9 +18,15 @@ nodes: nodes_path: /var/www/html/meshviewer/data/nodes_all.json nodesmini_path: /var/www/html/meshviewer/data/nodes.json graphs_path: /var/www/html/meshviewer/data/graph.json - saveinterval: 5 aliases_enable: false aliases_path: /var/www/html/meshviewer/data/aliases.json + + # Export nodes and graph every n seconds + saveinterval: 5 + + # Expire offline nodes after n days + max_age: 7 + influxdb: enable: false host: http://localhost:8086 diff --git a/jsontime/jsontime.go b/jsontime/jsontime.go index 399f78a..fb97f5c 100644 --- a/jsontime/jsontime.go +++ b/jsontime/jsontime.go @@ -29,7 +29,7 @@ func (t *Time) UnmarshalJSON(data []byte) (err error) { } return } -func (t Time) GetTime() time.Time{ +func (t Time) GetTime() time.Time { return t.time } func (t Time) Unix() int64 { @@ -46,3 +46,7 @@ func (t Time) Add(d time.Duration) Time { func (t Time) After(u Time) bool { return t.time.After(u.GetTime()) } + +func (t Time) Before(u Time) bool { + return t.time.Before(u.GetTime()) +} diff --git a/models/config.go b/models/config.go index 8e04e0c..fdd20e6 100644 --- a/models/config.go +++ b/models/config.go @@ -31,7 +31,8 @@ type Config struct { NodesMiniPath string `yaml:"nodesmini_path"` GraphsPath string `yaml:"graphs_path"` AliasesPath string `yaml:"aliases_path"` - SaveInterval int `yaml:"saveinterval"` + SaveInterval int `yaml:"saveinterval"` // Save nodes every n seconds + MaxAge int `yaml:"max_age"` // Remove nodes after n days of inactivity } `yaml:"nodes"` Influxdb struct { Enable bool `yaml:"enable"` diff --git a/models/nodes.go b/models/nodes.go index 9eaa516..d0e2a18 100644 --- a/models/nodes.go +++ b/models/nodes.go @@ -145,27 +145,53 @@ func (nodes *Nodes) worker() { c := time.Tick(time.Second * time.Duration(nodes.config.Nodes.SaveInterval)) for range c { - log.Println("saving", len(nodes.List), "nodes") - nodes.Timestamp = jsontime.Now() - nodes.Lock() - // - // set node as offline (without statistics) - for _, node := range nodes.List { - if node.Statistics != nil && nodes.Timestamp.After(node.Lastseen.Add(time.Second*time.Duration(10*nodes.config.Respondd.CollectInterval))) { - if node.Flags != nil { - node.Flags.Online = false - } + nodes.expire() + nodes.save() + } +} + +// Expires nodes and set nodes offline +func (nodes *Nodes) expire() { + nodes.Timestamp = jsontime.Now() + + // Nodes last seen before expireTime will be removed + maxAge := nodes.config.Nodes.MaxAge + if maxAge <= 0 { + maxAge = 7 // our default + } + expireTime := nodes.Timestamp.Add(-time.Duration(maxAge) * time.Hour * 24) + + // Nodes last seen before offlineTime are changed to 'offline' + offlineTime := nodes.Timestamp.Add(-time.Minute * 10) + + // Locking foo + nodes.Lock() + defer nodes.Unlock() + + for id, node := range nodes.List { + if node.Lastseen.Before(expireTime) { + // expire + delete(nodes.List, id) + } else if node.Lastseen.Before(offlineTime) { + // set to offline + if node.Flags != nil { + node.Flags.Online = false } } - // serialize nodes - save(nodes, nodes.config.Nodes.NodesPath) - save(nodes.GetNodesMini(), nodes.config.Nodes.NodesMiniPath) + } +} - if path := nodes.config.Nodes.GraphsPath; path != "" { - save(nodes.BuildGraph(), path) - } +func (nodes *Nodes) save() { + // Locking foo + nodes.RLock() + defer nodes.RUnlock() - nodes.Unlock() + // serialize nodes + save(nodes, nodes.config.Nodes.NodesPath) + save(nodes.GetNodesMini(), nodes.config.Nodes.NodesMiniPath) + + if path := nodes.config.Nodes.GraphsPath; path != "" { + save(nodes.BuildGraph(), path) } }