diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index b679d818d..b6eb4aa09 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 2f932a053..8eca00c5b 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) +}