Guard access to informer rpc client with mutex

Fixes data race

==================
WARNING: DATA RACE
Read at 0x00c02be544a8 by goroutine 4718:
  github.com/ipfs/ipfs-cluster/informer/disk.(*Informer).GetMetric()
      /home/iand/wip/iand/ipfs-cluster/informer/disk/disk.go:75 +0x135
  github.com/ipfs/ipfs-cluster.(*Cluster).sendInformerMetric()
      /home/iand/wip/iand/ipfs-cluster/cluster.go:279 +0x149
  github.com/ipfs/ipfs-cluster.(*Cluster).pushInformerMetrics()
      /home/iand/wip/iand/ipfs-cluster/cluster.go:324 +0x264
  github.com/ipfs/ipfs-cluster.(*Cluster).run.func3()
      /home/iand/wip/iand/ipfs-cluster/cluster.go:583 +0xba

Previous write at 0x00c02be544a8 by goroutine 3049:
  github.com/ipfs/ipfs-cluster/informer/disk.(*Informer).Shutdown()
      /home/iand/wip/iand/ipfs-cluster/informer/disk/disk.go:65 +0x10e
  github.com/ipfs/ipfs-cluster.(*Cluster).Shutdown()
      /home/iand/wip/iand/ipfs-cluster/cluster.go:768 +0x9d7
  github.com/ipfs/ipfs-cluster.shutdownCluster()
      /home/iand/wip/iand/ipfs-cluster/ipfscluster_test.go:420 +0x64
  github.com/ipfs/ipfs-cluster.shutdownClusters()
      /home/iand/wip/iand/ipfs-cluster/ipfscluster_test.go:414 +0x74
  github.com/ipfs/ipfs-cluster.TestClustersReplicationRealloc()
      /home/iand/wip/iand/ipfs-cluster/ipfscluster_test.go:1680 +0x10c6
  testing.tRunner()
      /opt/go/src/testing/testing.go:1194 +0x202

Goroutine 4718 (running) created at:
  github.com/ipfs/ipfs-cluster.(*Cluster).run()
      /home/iand/wip/iand/ipfs-cluster/cluster.go:581 +0x16d
  github.com/ipfs/ipfs-cluster.NewCluster.func1()
      /home/iand/wip/iand/ipfs-cluster/cluster.go:208 +0xa4

Goroutine 3049 (running) created at:
  testing.(*T).Run()
      /opt/go/src/testing/testing.go:1239 +0x5d7
  testing.runTests.func1()
      /opt/go/src/testing/testing.go:1512 +0xa6
  testing.tRunner()
      /opt/go/src/testing/testing.go:1194 +0x202
  testing.runTests()
      /opt/go/src/testing/testing.go:1510 +0x612
  testing.(*M).Run()
      /opt/go/src/testing/testing.go:1418 +0x3b3
  github.com/ipfs/ipfs-cluster.TestMain()
      /home/iand/wip/iand/ipfs-cluster/ipfscluster_test.go:134 +0x7dc
  main.main()
      _testmain.go:179 +0x271
==================
--- FAIL: TestClustersReplicationRealloc (13.60s)
    ipfscluster_test.go:1641: Shutting down QmYc1fpiBd7owHgDsnr42E7XtKZCTVjjm7FLnQMozcKid3
    testing.go:1093: race detected during execution of test
This commit is contained in:
Ian Davis 2021-07-28 13:03:42 +01:00
parent ea4dd7ed98
commit 33f1334c4a
No known key found for this signature in database
GPG Key ID: F3B290C645FE1783

View File

@ -5,6 +5,7 @@ package disk
import (
"context"
"fmt"
"sync"
"github.com/ipfs/ipfs-cluster/api"
@ -29,7 +30,9 @@ var logger = logging.Logger("diskinfo")
// Informer is a simple object to implement the ipfscluster.Informer
// and Component interfaces.
type Informer struct {
config *Config
config *Config // set when created, readonly
mu sync.Mutex // guards access to following fields
rpcClient *rpc.Client
}
@ -53,6 +56,8 @@ func (disk *Informer) Name() string {
// SetClient provides us with an rpc.Client which allows
// contacting other components in the cluster.
func (disk *Informer) SetClient(c *rpc.Client) {
disk.mu.Lock()
defer disk.mu.Unlock()
disk.rpcClient = c
}
@ -62,6 +67,9 @@ func (disk *Informer) Shutdown(ctx context.Context) error {
_, span := trace.StartSpan(ctx, "informer/disk/Shutdown")
defer span.End()
disk.mu.Lock()
defer disk.mu.Unlock()
disk.rpcClient = nil
return nil
}
@ -72,7 +80,11 @@ func (disk *Informer) GetMetric(ctx context.Context) *api.Metric {
ctx, span := trace.StartSpan(ctx, "informer/disk/GetMetric")
defer span.End()
if disk.rpcClient == nil {
disk.mu.Lock()
rpcClient := disk.rpcClient
disk.mu.Unlock()
if rpcClient == nil {
return &api.Metric{
Name: disk.Name(),
Valid: false,
@ -84,7 +96,7 @@ func (disk *Informer) GetMetric(ctx context.Context) *api.Metric {
valid := true
err := disk.rpcClient.CallContext(
err := rpcClient.CallContext(
ctx,
"",
"IPFSConnector",