From 4bea29f15ac2a3165328a6fc08ba2d45c6e5ee8f Mon Sep 17 00:00:00 2001 From: Aestek Date: Mon, 11 Mar 2019 15:48:19 +0100 Subject: [PATCH] [catalog] Update the node's services indexes on update (#5458) Node updates were not updating the service indexes, which are used for service related queries. This caused the X-Consul-Index to stay the same after a node update as seen from a service query even though the node data is returned in heath queries. If that happened in between queries the client would miss this change. We now update the indexes of the services on the node when it is updated. Fixes: #5450 --- agent/consul/state/catalog.go | 6 ++++++ agent/consul/state/catalog_test.go | 30 ++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index b679d818d4..b6eb4aa09c 100644 --- a/agent/consul/state/catalog.go +++ b/agent/consul/state/catalog.go @@ -481,6 +481,12 @@ func (s *Store) ensureNodeTxn(tx *memdb.Txn, idx uint64, node *structs.Node) err if err := tx.Insert("index", &IndexEntry{"nodes", idx}); err != nil { return fmt.Errorf("failed updating index: %s", err) } + // Update the node's service indexes as the node information is included + // in health queries and we would otherwise miss node updates in some cases + // for those queries. + if err := s.updateAllServiceIndexesOfNode(tx, idx, node.Node); err != nil { + return fmt.Errorf("failed updating index: %s", err) + } return nil } diff --git a/agent/consul/state/catalog_test.go b/agent/consul/state/catalog_test.go index 2f932a0536..8eca00c5b6 100644 --- a/agent/consul/state/catalog_test.go +++ b/agent/consul/state/catalog_test.go @@ -2980,8 +2980,8 @@ func TestStateStore_CheckServiceNodes(t *testing.T) { if err != nil { t.Fatalf("err: %s", err) } - // service1 has been registered at idx=6, other different registrations do not count - if idx != 6 { + // service1 has been updated by node on idx 8 + if idx != 8 { t.Fatalf("bad index: %d", idx) } @@ -3453,3 +3453,29 @@ func TestStateStore_NodeInfo_NodeDump(t *testing.T) { t.Fatalf("bad") } } + +func TestStateStore_ServiceIdxUpdateOnNodeUpdate(t *testing.T) { + s := testStateStore(t) + + // Create a service on a node + err := s.EnsureNode(10, &structs.Node{Node: "node", Address: "127.0.0.1"}) + require.Nil(t, err) + err = s.EnsureService(12, "node", &structs.NodeService{ID: "srv", Service: "srv", Tags: nil, Address: "", Port: 5000}) + require.Nil(t, err) + + // Store the current service index + ws := memdb.NewWatchSet() + lastIdx, _, err := s.ServiceNodes(ws, "srv") + require.Nil(t, err) + + // Update the node with some meta + err = s.EnsureNode(14, &structs.Node{Node: "node", Address: "127.0.0.1", Meta: map[string]string{"foo": "bar"}}) + require.Nil(t, err) + + // Read the new service index + ws = memdb.NewWatchSet() + newIdx, _, err := s.ServiceNodes(ws, "srv") + require.Nil(t, err) + + require.True(t, newIdx > lastIdx) +}