瀏覽代碼

chore(dht): keep ring of randezvous points

Signed-off-by: mudler <[email protected]>
mudler 1 年之前
父節點
當前提交
f60e426f36
共有 4 個文件被更改,包括 91 次插入11 次删除
  1. 8 11
      pkg/discovery/dht.go
  2. 26 0
      pkg/discovery/discovery_suite_test.go
  3. 20 0
      pkg/discovery/ring.go
  4. 37 0
      pkg/discovery/ring_test.go

+ 8 - 11
pkg/discovery/dht.go

@@ -38,14 +38,14 @@ type DHT struct {
 	KeyLength            int
 	RendezvousString     string
 	BootstrapPeers       AddrList
-	latestRendezvous     string
+	randezvousHistory    Ring
 	RefreshDiscoveryTime time.Duration
 	*dht.IpfsDHT
 	dhtOptions []dht.Option
 }
 
 func NewDHT(d ...dht.Option) *DHT {
-	return &DHT{dhtOptions: d}
+	return &DHT{dhtOptions: d, randezvousHistory: Ring{Length: 2}}
 }
 
 func (d *DHT) Option(ctx context.Context) func(c *libp2p.Config) error {
@@ -57,9 +57,7 @@ func (d *DHT) Option(ctx context.Context) func(c *libp2p.Config) error {
 func (d *DHT) Rendezvous() string {
 	if d.OTPKey != "" {
 		totp := internalCrypto.TOTP(sha256.New, d.KeyLength, d.OTPInterval, d.OTPKey)
-
 		rv := internalCrypto.MD5(totp)
-		d.latestRendezvous = rv
 		return rv
 	}
 	return d.RendezvousString
@@ -108,14 +106,13 @@ func (d *DHT) Run(c log.StandardLogger, ctx context.Context, host host.Host) err
 
 	connect := func() {
 		d.bootstrapPeers(c, ctx, host)
-		if d.latestRendezvous != "" {
-			c.Debugf("Announcing with old rendezvous: %s", d.latestRendezvous)
-			d.announceAndConnect(c, ctx, kademliaDHT, host, d.latestRendezvous)
-		}
-
 		rv := d.Rendezvous()
-		c.Debugf("Announcing with current rendezvous: %s", d.latestRendezvous)
-		d.announceAndConnect(c, ctx, kademliaDHT, host, rv)
+		d.randezvousHistory.Add(rv)
+
+		for _, r := range d.randezvousHistory.Data {
+			c.Debugf("Announcing with rendezvous: %s", r)
+			d.announceAndConnect(c, ctx, kademliaDHT, host, r)
+		}
 	}
 
 	go func() {

+ 26 - 0
pkg/discovery/discovery_suite_test.go

@@ -0,0 +1,26 @@
+/*
+Copyright © 2021-2024 Ettore Di Giacinto <[email protected]>
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package discovery_test
+
+import (
+	"testing"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+)
+
+func TestDiscovery(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Discovery Suite")
+}

+ 20 - 0
pkg/discovery/ring.go

@@ -0,0 +1,20 @@
+package discovery
+
+type Ring struct {
+	Data   []string
+	Length int
+}
+
+func (r *Ring) Add(s string) {
+	if len(r.Data) > 0 {
+		// Avoid duplicates of the last item
+		if r.Data[len(r.Data)-1] == s {
+			return
+		}
+	}
+
+	if len(r.Data)+1 > r.Length {
+		r.Data = r.Data[1:]
+	}
+	r.Data = append(r.Data, s)
+}

+ 37 - 0
pkg/discovery/ring_test.go

@@ -0,0 +1,37 @@
+/*
+Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package discovery_test
+
+import (
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+
+	. "github.com/mudler/edgevpn/pkg/discovery"
+)
+
+var _ = Describe("String utilities", func() {
+	Context("Ring", func() {
+		It("adds elements to the ring", func() {
+			R := Ring{Length: 3}
+			R.Add("a")
+			R.Add("b")
+			R.Add("c")
+			Expect(R.Data).To(Equal([]string{"a", "b", "c"}))
+			R.Add("d")
+			Expect(R.Data).To(Equal([]string{"b", "c", "d"}))
+			R.Add("d")
+			Expect(R.Data).To(Equal([]string{"b", "c", "d"}))
+		})
+	})
+})