Add stub database selection, and fix differences between pekoe and c-redis

- PUBSUB CHANNELS glob pattern matching
- Implement SELECT + max DB validation (0-15) (default db max is 16), for perl clients
- CLIENT KILL ID (single/range) + MAXAGE
- CLIENT INFO events + resp fields
- PUBSUB SHARDCHANNELS/SHARDNUMSUB stubs
This commit is contained in:
eleksir
2026-04-03 01:02:03 +03:00
parent 9e30243533
commit 92cd652b0d
5 changed files with 266 additions and 10 deletions

View File

@@ -31,6 +31,7 @@ type Client struct {
conn net.Conn
name string // Connection name set via CLIENT SETNAME
replyMode ReplyMode // Reply mode (ON/OFF/SKIP)
selectedDB int // Selected database index (via SELECT command)
flags uint64 // Client flags (e.g., paused, no-touch)
created time.Time // When the client connected
lastActive time.Time // Last activity time
@@ -48,6 +49,7 @@ func NewClient(conn net.Conn) *Client {
conn: conn,
name: "",
replyMode: ReplyOn,
selectedDB: 0,
flags: 0,
created: now,
lastActive: now,
@@ -89,6 +91,27 @@ func (c *Client) GetReplyMode() ReplyMode {
return c.replyMode
}
// SelectedDB returns the currently selected database index
func (c *Client) SelectedDB() int {
c.mu.RLock()
defer c.mu.RUnlock()
return c.selectedDB
}
// CreatedAt returns when the client connected
func (c *Client) CreatedAt() time.Time {
c.mu.RLock()
defer c.mu.RUnlock()
return c.created
}
// SetSelectedDB sets the selected database index
func (c *Client) SetSelectedDB(db int) {
c.mu.Lock()
defer c.mu.Unlock()
c.selectedDB = db
}
// UpdateActivity updates the last activity timestamp
func (c *Client) UpdateActivity() {
c.mu.Lock()
@@ -212,7 +235,7 @@ func (c *Client) LocalAddr() string {
}
// InfoString returns CLIENT INFO formatted string (Redis format)
// Format: id= addr= laddr= fd= age= idle= flags= db= sub= psub= multi= qbuf= qbuf-free= obl= oll= omem= tot-mem= cmd= user= redir=
// Format: id= addr= laddr= fd= age= idle= flags= db= sub= psub= multi= qbuf= qbuf-free= obl= oll= omem= tot-mem= events= cmd= user= redir= resp=
func (c *Client) InfoString() string {
c.mu.RLock()
defer c.mu.RUnlock()
@@ -229,16 +252,21 @@ func (c *Client) InfoString() string {
flags += "S"
}
// Events - indicate connection is active for read and write
events := "rw"
// Format: Redis CLIENT INFO format
return fmt.Sprintf("id=%d addr=%s laddr=%s fd=-1 age=%d idle=%d flags=%s db=0 sub=%d psub=%d multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 tot-mem=0 cmd=client user=default redir=-1",
return fmt.Sprintf("id=%d addr=%s laddr=%s fd=-1 age=%d idle=%d flags=%s db=%d sub=%d psub=%d multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 tot-mem=0 events=%s cmd=client user=default redir=-1 resp=2",
c.id,
c.RemoteAddr(),
c.LocalAddr(),
age,
idle,
flags,
c.selectedDB,
len(c.subscribed),
len(c.patterns),
events,
)
}