MCPcopy Index your code
hub / github.com/IBM-Cloud/go-etcd-rules

github.com/IBM-Cloud/go-etcd-rules @v1.7.32

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.7.32 ↗ · + Follow
601 symbols 1,833 edges 56 files 107 documented · 18% updated 15d agov1.7.32 · 2026-06-23★ 38
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

etcd-rules

Build Status License

NOTE: Built with the etcd 3.5.x client.

This is a rules engine for use with etcd. Simple dynamic rules allow the specification of keys based on the gin attribute syntax and the comparison to literals or other keys. These rules can be nested inside of AND, OR and NOT rules to enable the expression of complex relationships of values in etcd and the actions to be triggered when a set of conditions has been met. The engine watches etcd for updates and crawls the data tree at configurable intervals. This library makes use of the IBM-Cloud/go-etcd-lock library to enable concurrent monitoring by multiple application instances without collisions--the first client to obtain the lock processes the change while the others quickly fail to acquire the lock and move on. A trigger callback function should update the model if the action is successful so it is not retriggered. Recurring actions, such as continuous polling, can be implemented with rules that reference nodes with TTLs such that the expiration of a node triggers a rule and the callback adds back a node with the same key and TTL.

Import

# Master via standard import
go get github.com/IBM-Cloud/go-etcd-rules/rules

Example

package main

import (
    "context"
    "time"

    "github.com/IBM-Cloud/go-etcd-rules/rules"
    v3 "go.etcd.io/etcd/client/v3"
    "github.com/uber-go/zap"
)

func lTP(val string) *string {
    s := val
    return &s
}

func main() {
    logger := zap.New(
        zap.NewJSONEncoder(zap.RFC3339Formatter("ts")),
        zap.AddCaller(),
    )

    cfg := v3.Config{
        Endpoints: []string{"http://127.0.0.1:2379"},
    }

    engine := rules.NewV3Engine(cfg, logger)

    serverActive, err := rules.NewEqualsLiteralRule("/servers/:serverid/state", lTP("active"))
    if err != nil {
        panic(err)
    }
    pollDelayGone, err := rules.NewEqualsLiteralRule("/servers/internal/:serverid/poll_delay", nil)
    if err != nil {
        panic(err)
    }

    engine.AddRule(
        rules.NewAndRule(serverActive, pollDelayGone),
        "/:serverid/poll",
        pollServer,
        RuleID("example")
    )

    engine.Run()

    end := make(chan bool)
    <-end
}

func pollServer(task *rules.V3RuleTask) {
    cl, err := v3.New(task.Conf)
    if err != nil {
        return
    }
    kv := v3.NewKV(cl)
    resp, err := kv.Get(task.Context, task.Attr.Format("/servers/:serverid/ip"))
    if err != nil {
        return
    }
    if resp.Count == 0 {
        return
    }
    ip := string(resp.Kvs[0].Value)
    var status string
    if ping(ip.Node.Value) {
        status = "ok"
    } else {
        status = "down"
    }
    kv.Put(task.Context, task.Attr.Format("/servers/:serverid/status"), status)
    // Add new poll delay
    leaseCtx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    resp, err = cl.Grant(leaseCtx, int64(5))
    if err != nil {
        return
    }
    kv.Put(task.Context, task.Attr.Format("/servers/internal/:serverid/poll_delay"), "", v3.WithLease(resp.ID))
}

Extension points exported contracts — how you extend this code

AttributeFinder (Interface)
AttributeFinder is a more performant replacement for the GetAttribute method of Attributes. Internal functions use the F [4 …
rules/task.go
RuleLocker (Interface)
(no doc) [7 implementers]
rules/lock/lock.go
AdvancedMetricsCollector (Interface)
AdvancedMetricsCollector used for collecting metrics additional metrics beyond those required by the base MetricsCollect [3 …
rules/metrics_collector.go
V3Engine (Interface)
V3Engine defines the interactions with a rule engine instance communicating with etcd v3. [1 implementers]
rules/engine.go
DynamicRule (Interface)
DynamicRule defines rules that have dynamic key paths so that classes of keys can be referenced in rules. [1 implementers]
rules/dynamic_rule.go
ContextProvider (FuncType)
ContextProvider is used to specify a custom provider of a context for a given rule.
rules/options.go
WrapKV (FuncType)
WrapKV is used to provide a wrapper for the default etcd v3 KV implementation used by the rules engine.
rules/metrics.go
Attributes (Interface)
Attributes provide access to the key/value pairs associated with dynamic keys. For instance, a dynamic key "/static/:dy [3 …
rules/task.go

Core symbols most depended-on inside this repo

String
called by 47
rules/static_rule.go
NewEqualsLiteralRule
called by 35
rules/dynamic_rule.go
Unlock
called by 24
rules/lock/lock.go
satisfied
called by 23
rules/static_rule.go
Lock
called by 21
rules/lock/lock.go
NewAttributes
called by 19
rules/matcher.go
makeStaticRule
called by 19
rules/dynamic_rule.go
newMapReadAPI
called by 17
rules/dynamic_rule.go

Shape

Method 256
Function 229
Struct 78
Interface 25
FuncType 11
TypeAlias 2

Languages

Go100%

Modules by API surface

rules/dynamic_rule.go78 symbols
rules/static_rule.go55 symbols
rules/static_rule_test.go44 symbols
rules/options.go42 symbols
rules/matcher.go34 symbols
rules/engine.go33 symbols
rules/key_processor.go23 symbols
rules/metrics_collector.go20 symbols
rules/dynamic_rule_test.go20 symbols
metrics/prometheus_test.go16 symbols
rules/int_crawler.go14 symbols
metrics/prometheus.go14 symbols

For agents

$ claude mcp add go-etcd-rules \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page