From e06a5cc94b699f602ac51f23b6d09702cef226c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0trauch?= Date: Sat, 11 Sep 2021 11:58:27 +0200 Subject: [PATCH] Implementation of change detection If there is an update in discovery an function is triggered that can pick it up. --- daemon/main.go | 29 +++++++++++++++++++++++++++- daemon/update.go | 14 ++++++++++++++ go.mod | 1 + go.sum | 2 ++ server/tools.go | 12 ++++++++++++ server/tools_test.go | 45 ++++++++++++++++++++++++++++++++++++++++++++ server/types.go | 30 +++++++++++++++++++++++++++++ 7 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 daemon/update.go create mode 100644 server/tools.go create mode 100644 server/tools_test.go diff --git a/daemon/main.go b/daemon/main.go index 246bd4a..07f1bcb 100644 --- a/daemon/main.go +++ b/daemon/main.go @@ -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() diff --git a/daemon/update.go b/daemon/update.go new file mode 100644 index 0000000..a014689 --- /dev/null +++ b/daemon/update.go @@ -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 +} diff --git a/go.mod b/go.mod index c49ebdf..ce20073 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 4a8ce7d..dfa89ad 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/server/tools.go b/server/tools.go new file mode 100644 index 0000000..f017aad --- /dev/null +++ b/server/tools.go @@ -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) +} diff --git a/server/tools_test.go b/server/tools_test.go new file mode 100644 index 0000000..f23b76c --- /dev/null +++ b/server/tools_test.go @@ -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 +} diff --git a/server/types.go b/server/types.go index ebdf087..4309b0a 100644 --- a/server/types.go +++ b/server/types.go @@ -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