mirror of
https://github.com/tiennm99/keepalive.git
synced 2026-09-02 18:19:40 +00:00
feat(redis): add namespace counter key
This commit is contained in:
@@ -18,6 +18,7 @@ services:
|
||||
- adapter: redis
|
||||
config:
|
||||
url: redis://default@redis-a.example.com:6379
|
||||
namespace: keepalive
|
||||
|
||||
- adapter: mongodb
|
||||
config:
|
||||
@@ -43,7 +44,7 @@ services:
|
||||
|
||||
| `adapter` | Driver | `config` keys |
|
||||
| ------------ | ----------------------------------- | ------------- |
|
||||
| `redis` | `github.com/redis/go-redis/v9` | `url` |
|
||||
| `redis` | `github.com/redis/go-redis/v9` | `url`, optional `namespace` |
|
||||
| `valkey` | `github.com/valkey-io/valkey-go` | `url` |
|
||||
| `postgresql` | `github.com/lib/pq` | `url` |
|
||||
| `mysql` | `github.com/go-sql-driver/mysql` | `dsn` |
|
||||
@@ -88,7 +89,8 @@ go run .
|
||||
|
||||
On startup each adapter initializes the minimum resource it owns, then every tick performs the cheapest write that proves the cluster is alive. `counter_key` selects the key/doc ID and defaults to `counter`.
|
||||
|
||||
- **Redis/Valkey** — initialize with `SETNX key 0`, then `INCR key`
|
||||
- **Redis** — initialize with `SETNX key 0`, then `INCR key`. When `namespace` is empty, the key is `counter`; when `namespace: keepalive`, the key is `keepalive:counter`.
|
||||
- **Valkey** — initialize with `SETNX key 0`, then `INCR key`
|
||||
- **PostgreSQL** — `CREATE TABLE IF NOT EXISTS keepalive`, seed `key`, then `UPDATE ... RETURNING`
|
||||
- **MySQL** — `CREATE TABLE IF NOT EXISTS keepalive`, seed `key`, then `UPDATE` + `SELECT`
|
||||
- **MongoDB** — upsert `{_id: key, count: 0}` on connect, then `FindOneAndUpdate({_id: key}, {$inc: {count: 1}}, upsert)`
|
||||
|
||||
+10
-1
@@ -2,6 +2,7 @@ package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
@@ -14,7 +15,7 @@ func init() {
|
||||
}
|
||||
return &redisAdapter{
|
||||
url: url,
|
||||
key: cfg.Optional("counter_key", "counter"),
|
||||
key: redisCounterKey(cfg.Optional("counter_key", "counter"), cfg.Optional("namespace", "")),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@@ -52,3 +53,11 @@ func (a *redisAdapter) Close(_ context.Context) error {
|
||||
}
|
||||
return a.client.Close()
|
||||
}
|
||||
|
||||
func redisCounterKey(counterKey, namespace string) string {
|
||||
namespace = strings.TrimSpace(namespace)
|
||||
if namespace == "" {
|
||||
return counterKey
|
||||
}
|
||||
return namespace + ":" + counterKey
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package adapter
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestRedisFactoryUsesRootCounterKeyWithoutNamespace(t *testing.T) {
|
||||
got := newRedisAdapterForTest(t, Config{
|
||||
"url": "redis://cache.example.com:6379",
|
||||
"counter_key": "counter",
|
||||
})
|
||||
|
||||
if got.key != "counter" {
|
||||
t.Fatalf("key = %q, want %q", got.key, "counter")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedisFactoryPrefixesCounterKeyWithNamespace(t *testing.T) {
|
||||
got := newRedisAdapterForTest(t, Config{
|
||||
"url": "redis://cache.example.com:6379",
|
||||
"counter_key": "counter",
|
||||
"namespace": "keepalive",
|
||||
})
|
||||
|
||||
if got.key != "keepalive:counter" {
|
||||
t.Fatalf("key = %q, want %q", got.key, "keepalive:counter")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedisFactoryTreatsBlankNamespaceAsRoot(t *testing.T) {
|
||||
got := newRedisAdapterForTest(t, Config{
|
||||
"url": "redis://cache.example.com:6379",
|
||||
"counter_key": "counter",
|
||||
"namespace": " ",
|
||||
})
|
||||
|
||||
if got.key != "counter" {
|
||||
t.Fatalf("key = %q, want %q", got.key, "counter")
|
||||
}
|
||||
}
|
||||
|
||||
func newRedisAdapterForTest(t *testing.T, cfg Config) *redisAdapter {
|
||||
t.Helper()
|
||||
|
||||
adapterValue, err := Registry["redis"](cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("redis factory returned error: %v", err)
|
||||
}
|
||||
got, ok := adapterValue.(*redisAdapter)
|
||||
if !ok {
|
||||
t.Fatalf("redis factory returned %T, want *redisAdapter", adapterValue)
|
||||
}
|
||||
return got
|
||||
}
|
||||
@@ -6,6 +6,7 @@ services:
|
||||
- adapter: redis
|
||||
config:
|
||||
url: redis://default@redis-a.example.com:6379
|
||||
namespace: keepalive
|
||||
|
||||
- adapter: redis
|
||||
config:
|
||||
|
||||
Reference in New Issue
Block a user