Bladeren bron

:gear: Fixup data races

Ettore Di Giacinto 3 jaren geleden
bovenliggende
commit
6f8e482692
2 gewijzigde bestanden met toevoegingen van 35 en 7 verwijderingen
  1. 24 2
      pkg/blockchain/ledger.go
  2. 11 5
      pkg/services/alive_test.go

+ 24 - 2
pkg/blockchain/ledger.go

@@ -239,7 +239,8 @@ func (l *Ledger) Exists(b string, f func(Data) bool) (exists bool) {
 func (l *Ledger) CurrentData() map[string]map[string]Data {
 	l.Lock()
 	defer l.Unlock()
-	return l.blockchain.Last().Storage
+
+	return buckets(l.blockchain.Last().Storage).copy()
 }
 
 // LastBlock returns the last block in the blockchain
@@ -249,10 +250,31 @@ func (l *Ledger) LastBlock() Block {
 	return l.blockchain.Last()
 }
 
+type bucket map[string]Data
+
+func (b bucket) copy() map[string]Data {
+	copy := map[string]Data{}
+	for k, v := range b {
+		copy[k] = v
+	}
+	return copy
+}
+
+type buckets map[string]map[string]Data
+
+func (b buckets) copy() map[string]map[string]Data {
+	copy := map[string]map[string]Data{}
+	for k, v := range b {
+		copy[k] = bucket(v).copy()
+	}
+	return copy
+}
+
 // Add data to the blockchain
 func (l *Ledger) Add(b string, s map[string]interface{}) {
 	l.Lock()
-	current := l.blockchain.Last().Storage
+	current := buckets(l.blockchain.Last().Storage).copy()
+
 	for s, k := range s {
 		if _, exists := current[b]; !exists {
 			current[b] = make(map[string]Data)

+ 11 - 5
pkg/services/alive_test.go

@@ -36,12 +36,11 @@ var _ = Describe("Alive service", func() {
 	l := node.Logger(logg)
 
 	opts := append(
-		Alive(1*time.Second),
+		Alive(5*time.Second),
 		node.FromBase64(true, true, token),
-		node.WithStore(&blockchain.MemoryStore{}),
 		l)
-	e2 := node.New(opts...)
-	e1 := node.New(opts...)
+	e2 := node.New(append(opts, node.WithStore(&blockchain.MemoryStore{}))...)
+	e1 := node.New(append(opts, node.WithStore(&blockchain.MemoryStore{}))...)
 
 	Context("Aliveness check", func() {
 		It("detect both nodes alive after a while", func() {
@@ -51,8 +50,15 @@ var _ = Describe("Alive service", func() {
 			e1.Start(ctx)
 			e2.Start(ctx)
 
+			ll, _ := e1.Ledger()
+
+			ll.Persist(ctx, 1*time.Second, 100*time.Second, "t", "t", "test")
+
 			Eventually(func() []string {
-				ll, _ := e1.Ledger()
+				ll, err := e1.Ledger()
+				if err != nil {
+					return []string{}
+				}
 				return AvailableNodes(ll)
 			}, 100*time.Second, 1*time.Second).Should(ContainElement(e2.Host().ID().String()))
 		})