From a662acd79401bf7a461cf5ade1e7ac151665e63a Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Wed, 8 Oct 2014 13:28:59 -0700 Subject: [PATCH] consul: fix obscure bug when launching goroutines from for loop --- consul/internal_endpoint.go | 2 +- consul/rpc.go | 16 +++++----------- consul/structs/structs.go | 10 ---------- consul/structs/structs_test.go | 1 - 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/consul/internal_endpoint.go b/consul/internal_endpoint.go index e20e315da0..c27a078370 100644 --- a/consul/internal_endpoint.go +++ b/consul/internal_endpoint.go @@ -71,13 +71,13 @@ func (m *Internal) KeyringOperation( args *structs.KeyringRequest, reply *structs.KeyringResponses) error { - m.executeKeyringOp(args, reply, false) if !args.Forwarded { args.Forwarded = true m.executeKeyringOp(args, reply, true) return m.srv.globalRPC("Internal.KeyringOperation", args, reply) } + m.executeKeyringOp(args, reply, false) return nil } diff --git a/consul/rpc.go b/consul/rpc.go index 8fca85ff45..8956b0d0ff 100644 --- a/consul/rpc.go +++ b/consul/rpc.go @@ -229,29 +229,23 @@ func (s *Server) forwardDC(method, dc string, args interface{}, reply interface{ func (s *Server) globalRPC(method string, args interface{}, reply structs.CompoundResponse) error { - totalDC := len(s.remoteConsuls) - if totalDC == 1 { - return nil - } - errorCh := make(chan error) respCh := make(chan interface{}) // Make a new request into each datacenter for dc, _ := range s.remoteConsuls { - info := &structs.GenericRPC{Datacenter: dc} - go func() { + go func(dc string) { rr := reply.New() - if _, err := s.forward(method, info, args, &rr); err != nil { + if err := s.forwardDC(method, dc, args, &rr); err != nil { errorCh <- err return } respCh <- rr - }() + }(dc) } - replies := 0 - for replies < totalDC { + replies, total := 0, len(s.remoteConsuls) + for replies < total { select { case err := <-errorCh: return err diff --git a/consul/structs/structs.go b/consul/structs/structs.go index d655adf79a..b1f315271d 100644 --- a/consul/structs/structs.go +++ b/consul/structs/structs.go @@ -127,16 +127,6 @@ type QueryMeta struct { KnownLeader bool } -// GenericRPC is the simplest possible RPCInfo implementation -type GenericRPC struct { - Datacenter string - QueryOptions -} - -func (r *GenericRPC) RequestDatacenter() string { - return r.Datacenter -} - // RegisterRequest is used for the Catalog.Register endpoint // to register a node as providing a service. If no service // is provided, the node is registered. diff --git a/consul/structs/structs_test.go b/consul/structs/structs_test.go index abf8ebb744..cb7808731a 100644 --- a/consul/structs/structs_test.go +++ b/consul/structs/structs_test.go @@ -35,7 +35,6 @@ func TestEncodeDecode(t *testing.T) { func TestStructs_Implements(t *testing.T) { var ( - _ RPCInfo = &GenericRPC{} _ RPCInfo = &RegisterRequest{} _ RPCInfo = &DeregisterRequest{} _ RPCInfo = &DCSpecificRequest{}