[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
This commit is contained in:
Aestek 2019-03-11 15:48:19 +01:00 committed by Paul Banks
parent 774b39dd94
commit 071fcb28ba
2 changed files with 34 additions and 2 deletions

View File

@ -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 { if err := tx.Insert("index", &IndexEntry{"nodes", idx}); err != nil {
return fmt.Errorf("failed updating index: %s", err) 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 return nil
} }

View File

@ -2980,8 +2980,8 @@ func TestStateStore_CheckServiceNodes(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
// service1 has been registered at idx=6, other different registrations do not count // service1 has been updated by node on idx 8
if idx != 6 { if idx != 8 {
t.Fatalf("bad index: %d", idx) t.Fatalf("bad index: %d", idx)
} }
@ -3453,3 +3453,29 @@ func TestStateStore_NodeInfo_NodeDump(t *testing.T) {
t.Fatalf("bad") 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)
}