state: remove duplicate index on the checks table
By using a new pattern for more specific indexes. This allows us to use the same index for both service checks and node checks. It removes the abstraction around memdb.Txn operations, and isolates all of the enterprise differences in a single place (the indexer).
This commit is contained in:
parent
b781fec664
commit
88a9bd6d3c
|
@ -1315,9 +1315,14 @@ func (s *Store) deleteServiceTxn(tx WriteTxn, idx uint64, nodeName, serviceID st
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: accept a non-pointer value for EnterpriseMeta
|
||||||
|
if entMeta == nil {
|
||||||
|
entMeta = structs.DefaultEnterpriseMeta()
|
||||||
|
}
|
||||||
// Delete any checks associated with the service. This will invalidate
|
// Delete any checks associated with the service. This will invalidate
|
||||||
// sessions as necessary.
|
// sessions as necessary.
|
||||||
checks, err := catalogListServiceChecks(tx, nodeName, serviceID, entMeta)
|
q := NodeServiceQuery{Node: nodeName, Service: serviceID, EnterpriseMeta: *entMeta}
|
||||||
|
checks, err := tx.Get(tableChecks, indexNodeService, q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed service check lookup: %s", err)
|
return fmt.Errorf("failed service check lookup: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -1766,6 +1771,13 @@ func (s *Store) deleteCheckCASTxn(tx WriteTxn, idx, cidx uint64, node string, ch
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeServiceQuery is a type used to query the checks table.
|
||||||
|
type NodeServiceQuery struct {
|
||||||
|
Node string
|
||||||
|
Service string
|
||||||
|
structs.EnterpriseMeta
|
||||||
|
}
|
||||||
|
|
||||||
// deleteCheckTxn is the inner method used to call a health
|
// deleteCheckTxn is the inner method used to call a health
|
||||||
// check deletion within an existing transaction.
|
// check deletion within an existing transaction.
|
||||||
func (s *Store) deleteCheckTxn(tx WriteTxn, idx uint64, node string, checkID types.CheckID, entMeta *structs.EnterpriseMeta) error {
|
func (s *Store) deleteCheckTxn(tx WriteTxn, idx uint64, node string, checkID types.CheckID, entMeta *structs.EnterpriseMeta) error {
|
||||||
|
@ -2137,7 +2149,8 @@ func parseCheckServiceNodes(
|
||||||
// First add the node-level checks. These always apply to any
|
// First add the node-level checks. These always apply to any
|
||||||
// service on the node.
|
// service on the node.
|
||||||
var checks structs.HealthChecks
|
var checks structs.HealthChecks
|
||||||
iter, err := catalogListNodeChecks(tx, sn.Node)
|
q := NodeServiceQuery{Node: sn.Node, EnterpriseMeta: *structs.DefaultEnterpriseMeta()}
|
||||||
|
iter, err := tx.Get(tableChecks, indexNodeService, q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
@ -2147,7 +2160,8 @@ func parseCheckServiceNodes(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now add the service-specific checks.
|
// Now add the service-specific checks.
|
||||||
iter, err = catalogListServiceChecks(tx, sn.Node, sn.ServiceID, &sn.EnterpriseMeta)
|
q = NodeServiceQuery{Node: sn.Node, Service: sn.ServiceID, EnterpriseMeta: sn.EnterpriseMeta}
|
||||||
|
iter, err = tx.Get(tableChecks, indexNodeService, q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
memdb "github.com/hashicorp/go-memdb"
|
memdb "github.com/hashicorp/go-memdb"
|
||||||
|
|
||||||
|
@ -12,6 +13,34 @@ import (
|
||||||
|
|
||||||
func withEnterpriseSchema(_ *memdb.DBSchema) {}
|
func withEnterpriseSchema(_ *memdb.DBSchema) {}
|
||||||
|
|
||||||
|
func indexNodeServiceFromHealthCheck(raw interface{}) ([]byte, error) {
|
||||||
|
hc, ok := raw.(*structs.HealthCheck)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected type %T for structs.HealthCheck index", raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
if hc.Node == "" {
|
||||||
|
return nil, errMissingValueForIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
var b indexBuilder
|
||||||
|
b.String(strings.ToLower(hc.Node))
|
||||||
|
b.String(strings.ToLower(hc.ServiceID))
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexFromNodeServiceQuery(arg interface{}) ([]byte, error) {
|
||||||
|
hc, ok := arg.(NodeServiceQuery)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected type %T for NodeServiceQuery index", arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
var b indexBuilder
|
||||||
|
b.String(strings.ToLower(hc.Node))
|
||||||
|
b.String(strings.ToLower(hc.Service))
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func serviceIndexName(name string, _ *structs.EnterpriseMeta) string {
|
func serviceIndexName(name string, _ *structs.EnterpriseMeta) string {
|
||||||
return fmt.Sprintf("service.%s", name)
|
return fmt.Sprintf("service.%s", name)
|
||||||
}
|
}
|
||||||
|
@ -156,14 +185,6 @@ func catalogListChecks(tx ReadTxn, _ *structs.EnterpriseMeta) (memdb.ResultItera
|
||||||
return tx.Get("checks", "id")
|
return tx.Get("checks", "id")
|
||||||
}
|
}
|
||||||
|
|
||||||
func catalogListNodeChecks(tx ReadTxn, node string) (memdb.ResultIterator, error) {
|
|
||||||
return tx.Get("checks", indexNodeServiceCheck, node, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func catalogListServiceChecks(tx ReadTxn, node string, service string, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) {
|
|
||||||
return tx.Get("checks", indexNodeService, node, service)
|
|
||||||
}
|
|
||||||
|
|
||||||
func catalogInsertCheck(tx WriteTxn, chk *structs.HealthCheck, idx uint64) error {
|
func catalogInsertCheck(tx WriteTxn, chk *structs.HealthCheck, idx uint64) error {
|
||||||
// Insert the check
|
// Insert the check
|
||||||
if err := tx.Insert("checks", chk); err != nil {
|
if err := tx.Insert("checks", chk); err != nil {
|
||||||
|
|
|
@ -17,13 +17,12 @@ const (
|
||||||
tableGatewayServices = "gateway-services"
|
tableGatewayServices = "gateway-services"
|
||||||
tableMeshTopology = "mesh-topology"
|
tableMeshTopology = "mesh-topology"
|
||||||
|
|
||||||
indexID = "id"
|
indexID = "id"
|
||||||
indexServiceName = "service"
|
indexServiceName = "service"
|
||||||
indexConnect = "connect"
|
indexConnect = "connect"
|
||||||
indexKind = "kind"
|
indexKind = "kind"
|
||||||
indexStatus = "status"
|
indexStatus = "status"
|
||||||
indexNodeServiceCheck = "node_service_check"
|
indexNodeService = "node_service"
|
||||||
indexNodeService = "node_service"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// nodesTableSchema returns a new table schema used for storing node
|
// nodesTableSchema returns a new table schema used for storing node
|
||||||
|
@ -170,37 +169,13 @@ func checksTableSchema() *memdb.TableSchema {
|
||||||
Lowercase: true,
|
Lowercase: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
indexNodeServiceCheck: {
|
|
||||||
Name: indexNodeServiceCheck,
|
|
||||||
AllowMissing: true,
|
|
||||||
Unique: false,
|
|
||||||
Indexer: &memdb.CompoundIndex{
|
|
||||||
Indexes: []memdb.Indexer{
|
|
||||||
&memdb.StringFieldIndex{
|
|
||||||
Field: "Node",
|
|
||||||
Lowercase: true,
|
|
||||||
},
|
|
||||||
&memdb.FieldSetIndex{
|
|
||||||
Field: "ServiceID",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
indexNodeService: {
|
indexNodeService: {
|
||||||
Name: indexNodeService,
|
Name: indexNodeService,
|
||||||
AllowMissing: true,
|
AllowMissing: true,
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Indexer: &memdb.CompoundIndex{
|
Indexer: indexerSingle{
|
||||||
Indexes: []memdb.Indexer{
|
fromArgsIndexer: indexFromSingleArg(indexFromNodeServiceQuery),
|
||||||
&memdb.StringFieldIndex{
|
fromObjectIndexer: indexFromObject(indexNodeServiceFromHealthCheck),
|
||||||
Field: "Node",
|
|
||||||
Lowercase: true,
|
|
||||||
},
|
|
||||||
&memdb.StringFieldIndex{
|
|
||||||
Field: "ServiceID",
|
|
||||||
Lowercase: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,9 +52,7 @@ table=checks
|
||||||
index=node allow-missing
|
index=node allow-missing
|
||||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true
|
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true
|
||||||
index=node_service allow-missing
|
index=node_service allow-missing
|
||||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceID Lowercase=true] AllowMissing=false
|
indexer=github.com/hashicorp/consul/agent/consul/state.indexerSingle fromArgsIndexer=github.com/hashicorp/consul/agent/consul/state.indexFromSingleArg.func1 fromObjectIndexer=github.com/hashicorp/consul/agent/consul/state.indexNodeServiceFromHealthCheck
|
||||||
index=node_service_check allow-missing
|
|
||||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.FieldSetIndex Field=ServiceID] AllowMissing=false
|
|
||||||
index=service allow-missing
|
index=service allow-missing
|
||||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceName Lowercase=true
|
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceName Lowercase=true
|
||||||
index=status
|
index=status
|
||||||
|
|
Loading…
Reference in New Issue