diff --git a/consul/state/schema.go b/consul/state/schema.go index 006853a7f..f5c5193c3 100644 --- a/consul/state/schema.go +++ b/consul/state/schema.go @@ -177,6 +177,23 @@ func checksTableSchema() *memdb.TableSchema { Lowercase: true, }, }, + "node_service": &memdb.IndexSchema{ + Name: "node_service", + AllowMissing: true, + Unique: false, + Indexer: &memdb.CompoundIndex{ + Indexes: []memdb.Indexer{ + &memdb.StringFieldIndex{ + Field: "Node", + Lowercase: true, + }, + &memdb.StringFieldIndex{ + Field: "ServiceID", + Lowercase: true, + }, + }, + }, + }, }, } } diff --git a/consul/state/state_store.go b/consul/state/state_store.go index 22c8a779d..5fa6e7b2b 100644 --- a/consul/state/state_store.go +++ b/consul/state/state_store.go @@ -321,6 +321,20 @@ func (s *StateStore) deleteNodeServiceTxn(idx uint64, nodeID, serviceID string, return fmt.Errorf("failed service lookup: %s", err) } + // Delete any checks associated with the service + checks, err := tx.Get("checks", "node_service", nodeID, serviceID) + if err != nil { + return fmt.Errorf("failed service check lookup: %s", err) + } + for check := checks.Next(); check != nil; check = checks.Next() { + if err := tx.Delete("checks", check); err != nil { + return fmt.Errorf("failed deleting service check: %s", err) + } + } + if err := tx.Insert("index", &IndexEntry{"checks", idx}); err != nil { + return fmt.Errorf("failed updating index: %s", err) + } + // Delete the service and update the index if err := tx.Delete("services", service); err != nil { return fmt.Errorf("failed deleting service: %s", err) diff --git a/consul/state/state_store_test.go b/consul/state/state_store_test.go index ab9e1d0ff..423cd26ba 100644 --- a/consul/state/state_store_test.go +++ b/consul/state/state_store_test.go @@ -260,17 +260,41 @@ func TestStateStore_DeleteNodeService(t *testing.T) { t.Fatalf("bad: %#v (err: %#v)", ns, err) } - // Delete the service - if err := s.DeleteNodeService(3, "node1", "service1"); err != nil { + // Register a check with the service + check := &structs.HealthCheck{ + Node: "node1", + CheckID: "check1", + ServiceName: "redis", + ServiceID: "service1", + } + if err := s.EnsureCheck(3, check); err != nil { t.Fatalf("err: %s", err) } - // The service doesn't exist and the index was updated + // Service check exists + checks, err := s.NodeChecks("node1") + if err != nil { + t.Fatalf("err: %s", err) + } + if len(checks) != 1 { + t.Fatalf("wrong number of checks: %d", len(checks)) + } + + // Delete the service + if err := s.DeleteNodeService(4, "node1", "service1"); err != nil { + t.Fatalf("err: %s", err) + } + + // The service and check don't exist and the index was updated ns, err = s.NodeServices("node1") if err != nil || ns == nil || len(ns.Services) != 0 { t.Fatalf("bad: %#v (err: %#v)", ns, err) } - if idx := s.maxIndex("services"); idx != 3 { + checks, err = s.NodeChecks("node1") + if err != nil || len(checks) != 0 { + t.Fatalf("bad: %#v (err: %s)", checks, err) + } + if idx := s.maxIndex("services"); idx != 4 { t.Fatalf("bad index: %d", idx) } }