From 8fea5f8dc5c2dfb59653ef19d3512e0a22e6934a Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Mon, 24 Aug 2015 16:56:41 -0700 Subject: [PATCH] consul/state: track highest index when querying services --- consul/state/state_store.go | 23 ++++++++++++++++++++--- consul/state/state_store_test.go | 16 ++++++++++++++-- consul/structs/structs.go | 2 ++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/consul/state/state_store.go b/consul/state/state_store.go index 90b6f799d..4ef13fc90 100644 --- a/consul/state/state_store.go +++ b/consul/state/state_store.go @@ -157,13 +157,14 @@ func (s *StateStore) NodeServices(nodeID string) (*structs.NodeServices, error) defer tx.Abort() // Query the node - node, err := tx.First("nodes", "id", nodeID) + n, err := tx.First("nodes", "id", nodeID) if err != nil { return nil, fmt.Errorf("node lookup failed: %s", err) } - if node == nil { + if n == nil { return nil, nil } + node := n.(*structs.Node) // Read all of the services services, err := tx.Get("services", "node", nodeID) @@ -173,13 +174,25 @@ func (s *StateStore) NodeServices(nodeID string) (*structs.NodeServices, error) // Initialize the node services struct ns := &structs.NodeServices{ - Node: *node.(*structs.Node), + Node: *node, Services: make(map[string]*structs.NodeService), } + ns.CreateIndex = node.CreateIndex + ns.CreateIndex = node.CreateIndex // Add all of the services to the map for service := services.Next(); service != nil; service = services.Next() { sn := service.(*structs.ServiceNode) + + // Track the highest index + if sn.CreateIndex > ns.CreateIndex { + ns.CreateIndex = sn.CreateIndex + } + if sn.ModifyIndex > ns.ModifyIndex { + ns.ModifyIndex = sn.ModifyIndex + } + + // Create the NodeService svc := &structs.NodeService{ ID: sn.ServiceID, Service: sn.ServiceName, @@ -187,6 +200,10 @@ func (s *StateStore) NodeServices(nodeID string) (*structs.NodeServices, error) Address: sn.ServiceAddress, Port: sn.ServicePort, } + svc.CreateIndex = sn.CreateIndex + svc.ModifyIndex = sn.ModifyIndex + + // Add the service to the result ns.Services[svc.ID] = svc } diff --git a/consul/state/state_store_test.go b/consul/state/state_store_test.go index 94c8a4636..c133a87db 100644 --- a/consul/state/state_store_test.go +++ b/consul/state/state_store_test.go @@ -142,10 +142,22 @@ func TestStateStore_EnsureService_NodeServices(t *testing.T) { if out == nil || len(out.Services) != 2 { t.Fatalf("bad services: %#v", out) } - if svc := out.Services["service1"]; !reflect.DeepEqual(ns1, svc) { + + // Results match the inserted services and have the proper indexes set + expect1 := *ns1 + expect1.CreateIndex, expect1.ModifyIndex = 10, 10 + if svc := out.Services["service1"]; !reflect.DeepEqual(&expect1, svc) { t.Fatalf("bad: %#v", svc) } - if svc := out.Services["service2"]; !reflect.DeepEqual(&ns2, svc) { + + expect2 := ns2 + expect2.CreateIndex, expect2.ModifyIndex = 20, 20 + if svc := out.Services["service2"]; !reflect.DeepEqual(&expect2, svc) { t.Fatalf("bad: %#v %#v", ns2, svc) } + + // Lastly, ensure that the highest index was preserved. + if out.CreateIndex != 20 || out.ModifyIndex != 20 { + t.Fatalf("bad index: %d, %d", out.CreateIndex, out.ModifyIndex) + } } diff --git a/consul/structs/structs.go b/consul/structs/structs.go index 213e3af62..586aff168 100644 --- a/consul/structs/structs.go +++ b/consul/structs/structs.go @@ -269,6 +269,8 @@ type NodeService struct { type NodeServices struct { Node Node Services map[string]*NodeService + + Index } // HealthCheck represents a single check on a given node