proxy-pool/internal/adapters/redisactivity/keys.go
youfak 3421ad5e14
Some checks are pending
ci / proto (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
ci / race (push) Waiting to run
ci / integration (push) Waiting to run
feat: add redis basic health task broker
2026-07-31 21:48:59 +08:00

132 lines
3.9 KiB
Go

package redisactivity
import (
"crypto/sha256"
"encoding/hex"
"strconv"
)
const redisKeyPrefix = "pp:{activity}:"
type keyspace struct {
prefix string
records string
unique string
idkeys string
expiry string
available string
owners string
ownerExpiry string
epoch string
inventory string
stateInventory string
workerSessions string
workerSessionExpiry string
workerSnapshots string
workerSnapshotExpiry string
workerRuntime string
workerRuntimeExpiry string
workerOutcomes string
healthDue string
healthQueued string
healthLeases string
healthTasks string
healthTaskExpiry string
healthRefTask string
}
func newKeyspace(namespace string) keyspace {
prefix := redisKeyPrefix + namespace
return keyspace{
prefix: prefix,
records: prefix + ":records",
unique: prefix + ":unique",
idkeys: prefix + ":idkeys",
expiry: prefix + ":expiry",
available: prefix + ":available",
owners: prefix + ":owners",
ownerExpiry: prefix + ":owner-expiry",
epoch: prefix + ":epoch",
inventory: prefix + ":inventory",
stateInventory: prefix + ":state-inventory",
workerSessions: prefix + ":worker-sessions",
workerSessionExpiry: prefix + ":worker-session-expiry",
workerSnapshots: prefix + ":worker-snapshots",
workerSnapshotExpiry: prefix + ":worker-snapshot-expiry",
workerRuntime: prefix + ":worker-runtime",
workerRuntimeExpiry: prefix + ":worker-runtime-expiry",
workerOutcomes: prefix + ":worker-outcomes",
healthDue: prefix + ":health-due",
healthQueued: prefix + ":health-queued",
healthLeases: prefix + ":health-leases",
healthTasks: prefix + ":health-tasks",
healthTaskExpiry: prefix + ":health-task-expiry",
healthRefTask: prefix + ":health-ref-task",
}
}
func (keys keyspace) checkerLeases(checkerID string) string {
return keys.prefix + ":health-checker-leases:" + digestToken(checkerID)
}
func stateInventoryField(upstreamID, state string) string {
return strconv.Itoa(len(upstreamID)) + ":" + upstreamID + ":" + state
}
func (keys keyspace) idempotency(clientID, idempotencyKey string) string {
return keys.prefix + ":idem:" + digestParts(clientID, idempotencyKey)
}
func (keys keyspace) operation(operationID string) string {
return keys.prefix + ":op:" + digestToken(operationID)
}
// targetHealth stores short-lived TARGET check state separately from the
// proxy record. The proxy ID is hashed so neither endpoint identity nor target
// profile information appears in a Redis key name.
func (keys keyspace) targetHealth(proxyID string) string {
return keys.prefix + ":target-health:" + digestToken(proxyID)
}
func (keys keyspace) protocol(value string) string {
return keys.facet("protocol", value)
}
func (keys keyspace) region(value string) string {
return keys.facet("region", value)
}
func (keys keyspace) carrier(value string) string {
return keys.facet("carrier", value)
}
func (keys keyspace) upstream(value string) string {
return keys.facet("upstream", value)
}
func (keys keyspace) owned(value string) string {
return keys.facet("owned", value)
}
func (keys keyspace) workerOwned(workerID string) string {
return keys.facet("worker-owned", workerID)
}
func (keys keyspace) facet(name, value string) string {
return keys.prefix + ":" + name + ":" + digestToken(value)
}
func digestToken(value string) string {
return digestParts(value)
}
func digestParts(values ...string) string {
digest := sha256.New()
for _, value := range values {
_, _ = digest.Write([]byte(strconv.Itoa(len(value))))
_, _ = digest.Write([]byte{':'})
_, _ = digest.Write([]byte(value))
}
return hex.EncodeToString(digest.Sum(nil))
}