Implementation of change detection

If there is an update in discovery an function is triggered
that can pick it up.
This commit is contained in:
Adam Štrauch 2021-09-11 11:58:27 +02:00
parent 6769b903bc
commit e06a5cc94b
Signed by: cx
GPG Key ID: 018304FFA8988F8D
7 changed files with 132 additions and 1 deletions

View File

@ -137,12 +137,39 @@ func main() {
// Server discovering stuff
// ------------------------
// Connect to the NATS service
// Setup callback function to register and unregister discovery packets from other servers
driver.RegisterSubscribeFunction(func(d server.Discovery) {
// Check if the local version and the new version are somehow changed
localVersion := discoveryStorage.Get(d.Hostname)
exists := discoveryStorage.Exist(d.Hostname)
changed := server.Compare(localVersion, d)
discoveryStorage.Add(d)
if changed {
// Print this only if the server is already registered
if exists {
log.Printf("%s has been updated", d.Hostname)
}
go func() {
err = discoveryChange(d)
if err != nil {
log.Printf("discovery changed error: %v", err)
}
}()
}
})
driver.RegisterUnsubscribeFunction(func(d server.Discovery) {
discoveryStorage.Delete(d.Hostname)
go func() {
err = discoveryChange(d)
if err != nil {
log.Printf("discovery changed error: %v", err)
}
}()
})
err = driver.Init()

14
daemon/update.go Normal file
View File

@ -0,0 +1,14 @@
package main
import (
"github.com/by-cx/lobby/server"
)
// These functions are called when something has changed in the storage
// discoveryChange is called when daemon detects that a newly arrived discovery
// packet is somehow different than the localone. This can be used to trigger
// some action in the local machine.
func discoveryChange(discovery server.Discovery) error {
return nil
}

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/fatih/color v1.12.0
github.com/go-redis/redis v6.15.9+incompatible
github.com/go-resty/resty/v2 v2.6.0
github.com/google/go-cmp v0.5.5
github.com/kelseyhightower/envconfig v1.4.0
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0 // indirect

2
go.sum
View File

@ -31,6 +31,7 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
@ -148,6 +149,7 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

12
server/tools.go Normal file
View File

@ -0,0 +1,12 @@
package server
import "github.com/google/go-cmp/cmp"
// Compare compares discovery A and B and returns true if those two are different.
func Compare(discoveryA, discoveryB Discovery) bool {
discoveryA.LastCheck = 0
discoveryB.LastCheck = 0
discoveryA.TTL = 0
discoveryB.TTL = 0
return !cmp.Equal(discoveryA, discoveryB)
}

45
server/tools_test.go Normal file
View File

@ -0,0 +1,45 @@
package server
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCompare(t *testing.T) {
discoveryA := Discovery{
Hostname: "abcd.com",
Labels: Labels{
Label("label1"),
},
LastCheck: 52,
}
discoveryAB := Discovery{
Hostname: "abcd.com",
Labels: Labels{
Label("label1"),
},
LastCheck: 56,
}
discoveryB := Discovery{
Hostname: "efgh.com",
Labels: Labels{
Label("label2"),
},
LastCheck: 56,
}
discoveryC := Discovery{
Hostname: "abcd.com",
Labels: Labels{
Label("label2"),
},
LastCheck: 60,
}
assert.True(t, Compare(discoveryA, discoveryB))
assert.True(t, Compare(discoveryB, discoveryC))
assert.True(t, Compare(discoveryA, discoveryC)) // Test different labels and same hostname
assert.False(t, Compare(discoveryA, discoveryA))
assert.False(t, Compare(discoveryB, discoveryB))
assert.False(t, Compare(discoveryA, discoveryAB)) // Test that last check is zeroed
}

View File

@ -1,5 +1,7 @@
package server
import "strings"
// Label keeps one piece of information about a single server
type Label string
@ -7,6 +9,34 @@ func (l Label) String() string {
return string(l)
}
// GetPart returns specific part of the label, if part index is higher than last available index it returns empty string.
func (l Label) GetPart(idx int) string {
parts := strings.Split(l.String(), ":")
if idx < 0 {
return ""
}
if len(parts) >= idx {
return ""
}
return parts[idx]
}
// GetPart1 is exactly same as GetPart but it splits the label only once, this is good for IPv6 addresses
func (l Label) GetPart1(idx int) string {
parts := strings.SplitN(l.String(), ":", 2)
if idx < 0 {
return ""
}
if len(parts) >= idx {
return ""
}
return parts[idx]
}
// Labels stores multiple Label records
type Labels []Label