docs(config): add interval and counter examples

This commit is contained in:
2026-06-29 11:34:59 +07:00
parent 30660b95f5
commit afa710289c
4 changed files with 39 additions and 4 deletions
+6 -2
View File
@@ -22,8 +22,9 @@ services:
namespace: keepalive
- adapter: valkey
# One service can override the global interval.
# One service can override the global interval and counter key.
interval: 30s
counter_key: valkey-counter
config:
url: valkey://default@valkey-a.example.com:6379
@@ -56,8 +57,11 @@ services:
`interval` at the root sets the default schedule for every service and defaults to `1m`.
`interval` inside a service overrides that default only for that service.
In the example above, every service runs every `1m` except `valkey`, which runs every `30s`.
Interval values use Go duration syntax, for example `30s`, `5m`, `1h`, `1h30m`, or `1.5h`. Plain integers are treated as seconds, so `90` means `90s`.
`counter_key` can be set globally or per service. Per-service values override global values.
`counter_key` at the root sets the default counter key for every service and defaults to `counter`.
`counter_key` inside a service overrides that default only for that service.
In the example above, every service writes `counter` except `valkey`, which writes `valkey-counter`.
## Supported adapters
+3 -1
View File
@@ -1,4 +1,5 @@
# Optional default interval shared by every service.
# Examples: 30s, 5m, 1h, 1h30m, 1.5h, or 90 for 90 seconds.
interval: 1m
counter_key: counter
@@ -9,8 +10,9 @@ services:
namespace: keepalive
- adapter: valkey
# Example: this service runs every 30s while others use the root interval.
# Example: this service overrides root interval and counter_key.
interval: 30s
counter_key: valkey-counter
config:
url: valkey://default@valkey-a.example.com:6379
+1 -1
View File
@@ -138,7 +138,7 @@ func parseConfigInterval(field, value string, def time.Duration) (time.Duration,
}
return d, nil
}
return 0, fmt.Errorf("%s must be a duration like 30s or an integer number of seconds", field)
return 0, fmt.Errorf("%s must be a duration like 30s, 5m, or 1h30m, or an integer number of seconds", field)
}
func valueOrDefault(value, def string) string {
+29
View File
@@ -51,6 +51,15 @@ func TestConfigExampleYMLParses(t *testing.T) {
if services[2].Interval != time.Minute {
t.Fatalf("services[2].Interval = %s, want 1m", services[2].Interval)
}
if services[0].Config["counter_key"] != "counter" {
t.Fatalf("services[0] counter_key = %q, want counter", services[0].Config["counter_key"])
}
if services[1].Config["counter_key"] != "valkey-counter" {
t.Fatalf("services[1] counter_key = %q, want valkey-counter", services[1].Config["counter_key"])
}
if services[2].Config["counter_key"] != "counter" {
t.Fatalf("services[2] counter_key = %q, want counter", services[2].Config["counter_key"])
}
}
func TestFirstExistingConfigFileFindsYMLFallback(t *testing.T) {
@@ -156,6 +165,26 @@ func TestNormalizeConfigAppliesGlobalAndServiceDefaults(t *testing.T) {
}
}
func TestNormalizeConfigParsesCompoundAndFractionalIntervals(t *testing.T) {
services, err := normalizeConfig(appConfig{
Interval: "1h30m",
Services: []serviceFileConfig{
{Adapter: "redis", Config: map[string]string{"url": "redis://cache.example.com:6379"}},
{Adapter: "redis", Interval: "1.5h", Config: map[string]string{"url": "redis://other.example.com:6379"}},
},
})
if err != nil {
t.Fatalf("normalizeConfig returned error: %v", err)
}
if services[0].Interval != 90*time.Minute {
t.Fatalf("services[0].Interval = %s, want 1h30m", services[0].Interval)
}
if services[1].Interval != 90*time.Minute {
t.Fatalf("services[1].Interval = %s, want 1.5h", services[1].Interval)
}
}
func TestNormalizeConfigRejectsNonPositiveInterval(t *testing.T) {
_, err := normalizeConfig(appConfig{
Interval: "0s",