Files
the-other-dude/poller/internal/bus/redis_locker.go
Jason Staack 0851eced36 feat(04-01): implement BackupResponder with extracted CollectAndPublish
- Create BackupResponder for NATS request-reply on config.backup.trigger
- Extract public CollectAndPublish from BackupScheduler returning sha256 hash
- Define BackupExecutor/BackupLocker/DeviceGetter interfaces for testability
- Create RedisBackupLocker adapter wrapping redislock.Client
- Wire BackupResponder into main.go lifecycle
- All 6 tests pass with in-process NATS server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:07:35 -05:00

42 lines
1.1 KiB
Go

package bus
import (
"context"
"time"
"github.com/bsm/redislock"
)
// RedisBackupLocker adapts *redislock.Client to the BackupLocker interface.
type RedisBackupLocker struct {
client *redislock.Client
}
// NewRedisBackupLocker wraps a redislock.Client for use by BackupResponder.
func NewRedisBackupLocker(client *redislock.Client) *RedisBackupLocker {
return &RedisBackupLocker{client: client}
}
// ObtainLock attempts to acquire a Redis distributed lock.
// Returns ErrLockNotObtained if the lock is already held.
func (l *RedisBackupLocker) ObtainLock(ctx context.Context, key string, ttl time.Duration) (BackupLockHandle, error) {
lock, err := l.client.Obtain(ctx, key, ttl, nil)
if err == redislock.ErrNotObtained {
return nil, ErrLockNotObtained
}
if err != nil {
return nil, err
}
return &redisLockHandle{lock: lock}, nil
}
// redisLockHandle wraps *redislock.Lock to implement BackupLockHandle.
type redisLockHandle struct {
lock *redislock.Lock
}
// Release releases the held Redis lock.
func (h *redisLockHandle) Release(ctx context.Context) error {
return h.lock.Release(ctx)
}