...
This commit is contained in:
68
pkg/servers/redisserver/factory.go
Normal file
68
pkg/servers/redisserver/factory.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package redisserver
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// entry represents a stored value. For strings, value is stored as a string.
|
||||
// For hashes, value is stored as a map[string]string.
|
||||
type entry struct {
|
||||
value interface{}
|
||||
expiration time.Time // zero means no expiration
|
||||
}
|
||||
|
||||
// Server holds the in-memory datastore and provides thread-safe access.
|
||||
// It implements a Redis-compatible server using redcon.
|
||||
type Server struct {
|
||||
mu sync.RWMutex
|
||||
data map[string]*entry
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
TCPPort string
|
||||
UnixSocketPath string
|
||||
}
|
||||
|
||||
// NewCustomServer creates a new server instance with custom TCP port and Unix socket path.
|
||||
// It starts a cleanup goroutine and Redis-compatible servers on the specified addresses.
|
||||
func NewServer(config ServerConfig) *Server {
|
||||
|
||||
if config.UnixSocketPath == "" {
|
||||
config.UnixSocketPath = "/tmp/redis.sock"
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
data: make(map[string]*entry),
|
||||
}
|
||||
go s.cleanupExpiredKeys()
|
||||
|
||||
// Start TCP server if port is provided
|
||||
if config.TCPPort != "" {
|
||||
tcpAddr := ":" + config.TCPPort
|
||||
go s.startRedisServer(tcpAddr, "")
|
||||
}
|
||||
|
||||
// Start Unix socket server if path is provided
|
||||
if config.UnixSocketPath != "" {
|
||||
go s.startRedisServer(config.UnixSocketPath, "unix")
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// cleanupExpiredKeys periodically removes expired keys.
|
||||
func (s *Server) cleanupExpiredKeys() {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
now := time.Now()
|
||||
s.mu.Lock()
|
||||
for k, ent := range s.data {
|
||||
if !ent.expiration.IsZero() && now.After(ent.expiration) {
|
||||
delete(s.data, k)
|
||||
}
|
||||
}
|
||||
s.mu.Unlock()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user