Skip to content

Commit 616e605

Browse files
committed
Refactor codebase by improving readability across multiple files
1 parent 4defd9c commit 616e605

5 files changed

Lines changed: 73 additions & 826 deletions

File tree

commands.go

Lines changed: 21 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,34 @@
1-
/*
2-
Package redkit provides a comprehensive Redis-compatible server implementation.
3-
4-
This file defines all Redis command types and their registration helper functions.
5-
The commands are organized into functional categories following Redis documentation.
6-
7-
Command Categories:
8-
- Connection Commands: Basic server communication (PING, ECHO, QUIT)
9-
- String Commands: String operations (GET, SET, INCR, APPEND, etc.)
10-
- Hash Commands: Hash table operations (HGET, HSET, HKEYS, etc.)
11-
- List Commands: List operations (LPUSH, RPOP, LRANGE, etc.)
12-
- Set Commands: Set operations (SADD, SREM, SMEMBERS, etc.)
13-
- Sorted Set Commands: Ordered set operations (ZADD, ZRANGE, ZSCORE, etc.)
14-
- Stream Commands: Stream data structure operations (XADD, XREAD, etc.)
15-
- Bitmap Commands: Bit manipulation (BITCOUNT, SETBIT, GETBIT, etc.)
16-
- HyperLogLog Commands: Probabilistic cardinality estimation (PFADD, PFCOUNT, etc.)
17-
- Geospatial Commands: Geographic operations (GEOADD, GEORADIUS, etc.)
18-
- JSON Commands: JSON data operations (JSON.GET, JSON.SET, etc.)
19-
- Search Commands: Full-text search (FT.SEARCH, FT.CREATE, etc.)
20-
- Time Series Commands: Time-series data (TS.ADD, TS.RANGE, etc.)
21-
- Vector Set Commands: Vector similarity operations (VADD, VSIM, etc.)
22-
- Pub/Sub Commands: Message publishing/subscribing (PUBLISH, SUBSCRIBE, etc.)
23-
- Transaction Commands: Atomic operations (MULTI, EXEC, WATCH, etc.)
24-
- Scripting Commands: Lua script execution (EVAL, EVALSHA, etc.)
25-
- Server Commands: Server management (INFO, CONFIG, SAVE, etc.)
26-
- Cluster Commands: Redis cluster operations (CLUSTER, ASKING, etc.)
27-
- Generic Commands: Key management (DEL, EXISTS, EXPIRE, TTL, etc.)
28-
29-
Usage Example:
30-
31-
server := redkit.NewServer()
32-
33-
// Register custom GET handler
34-
server.registerGetHandler(func(conn *Connection, cmd *Command) RedisValue {
35-
// Custom GET implementation
36-
return RedisValue{Type: SimpleString, Str: "value"}
37-
})
38-
39-
// Start server
40-
server.ListenAndServe(":6379")
41-
42-
Each command has a corresponding registration helper function that follows the pattern:
43-
44-
register{CommandName}Handler(f func(conn *Connection, cmd *Command) RedisValue)
45-
46-
This allows for easy customization and extension of command behavior while maintaining
47-
Redis protocol compatibility.
48-
*/
491
package redkit
502

51-
// CommandType represents Redis command names as typed string constants
52-
// This ensures type safety and provides intellisense support for command names
3+
// CommandType represents Redis command names
534
type CommandType string
545

55-
/*
56-
Redis Command Type Constants
57-
58-
All Redis commands are defined as strongly-typed constants to prevent typos
59-
and provide IDE autocompletion. Commands are organized by functional category
60-
matching the official Redis documentation structure.
61-
62-
The constants follow the exact Redis command names (case-sensitive) to ensure
63-
protocol compatibility.
64-
*/
656
const (
66-
// Connection Commands - Basic server communication
7+
// Connection Commands
678
PING CommandType = "PING" // Test server connectivity
689
ECHO CommandType = "ECHO" // Echo the given string
6910
QUIT CommandType = "QUIT" // Close the connection
7011
HELP CommandType = "HELP" // Show help information
7112

72-
// String Commands - Operations on string values
73-
APPEND CommandType = "APPEND" // Append a value to a key
74-
DECR CommandType = "DECR" // Decrement the integer value of a key by 1
75-
DECRBY CommandType = "DECRBY" // Decrement the integer value of a key by the given amount
76-
DELEX CommandType = "DELEX" // Delete key based on value comparison
77-
DIGEST CommandType = "DIGEST" // Return hash digest of a string value
78-
GET CommandType = "GET" // Get the value of a key
79-
GETDEL CommandType = "GETDEL" // Get the value of a key and delete the key
80-
GETEX CommandType = "GETEX" // Get the value of a key and set its expiration
81-
GETRANGE CommandType = "GETRANGE" // Get a substring of the string stored at a key
82-
GETSET CommandType = "GETSET" // Set the value of a key and return its old value
83-
INCR CommandType = "INCR" // Increment the integer value of a key by 1
84-
INCRBY CommandType = "INCRBY" // Increment the integer value of a key by the given amount
85-
INCRBYFLOAT CommandType = "INCRBYFLOAT" // Increment the float value of a key by the given amount
86-
LCS CommandType = "LCS" // Find the longest common substring
87-
MGET CommandType = "MGET" // Get the values of all the given keys
88-
MSET CommandType = "MSET" // Set multiple keys to multiple values
89-
MSETEX CommandType = "MSETEX" // Set multiple keys with expiration time
90-
MSETNX CommandType = "MSETNX" // Set multiple keys to multiple values, only if none exist
13+
// String Commands
14+
APPEND CommandType = "APPEND"
15+
DECR CommandType = "DECR"
16+
DECRBY CommandType = "DECRBY"
17+
DELEX CommandType = "DELEX"
18+
DIGEST CommandType = "DIGEST"
19+
GET CommandType = "GET"
20+
GETDEL CommandType = "GETDEL"
21+
GETEX CommandType = "GETEX"
22+
GETRANGE CommandType = "GETRANGE"
23+
GETSET CommandType = "GETSET"
24+
INCR CommandType = "INCR"
25+
INCRBY CommandType = "INCRBY"
26+
INCRBYFLOAT CommandType = "INCRBYFLOAT"
27+
LCS CommandType = "LCS"
28+
MGET CommandType = "MGET"
29+
MSET CommandType = "MSET"
30+
MSETEX CommandType = "MSETEX"
31+
MSETNX CommandType = "MSETNX"
9132
PSETEX CommandType = "PSETEX"
9233
SET CommandType = "SET"
9334
SETEX CommandType = "SETEX"
@@ -440,23 +381,6 @@ const (
440381
WAITAOF CommandType = "WAITAOF"
441382
)
442383

443-
/*
444-
Default Command Handlers
445-
446-
registerDefaultHandlers sets up the basic Redis protocol commands that are
447-
essential for client connectivity and server interaction. These handlers
448-
implement the minimum functionality required for Redis compatibility:
449-
450-
- PING: Connectivity testing with optional message echo
451-
- ECHO: Simple string echo for testing
452-
- HELP: Basic command information
453-
- QUIT: Graceful connection termination
454-
455-
Custom implementations can override these by registering new handlers
456-
with the same command names, or extend functionality by registering
457-
additional commands.
458-
*/
459-
460384
// registerDefaultHandlers registers the built-in Redis commands
461385
func (s *Server) registerDefaultHandlers() {
462386
// PING command
@@ -494,48 +418,22 @@ func (s *Server) registerDefaultHandlers() {
494418
})
495419
}
496420

497-
/*
498-
Command Registration Helper Functions
499-
500-
These functions provide a convenient way to register custom handlers for Redis commands.
501-
Each function follows the pattern: register{CommandName}Handler(handlerFunc)
502-
503-
The handler function signature is always:
504-
func(conn *Connection, cmd *Command) RedisValue
505-
506-
Where:
507-
- conn: The client connection context
508-
- cmd: The parsed command with arguments
509-
- RedisValue: The response to send back to the client
510-
511-
Example usage:
512-
server.registerGetHandler(func(conn *Connection, cmd *Command) RedisValue {
513-
key := cmd.Args[0]
514-
value := myStorage.Get(key)
515-
return RedisValue{Type: BulkString, Bulk: []byte(value)}
516-
})
517-
*/
518-
519421
// registerPingHandler registers a custom handler for the PING command
520-
// PING [message] - Test connectivity and optionally echo a message
521422
func (s *Server) registerPingHandler(f func(conn *Connection, cmd *Command) RedisValue) {
522423
s.RegisterCommandFunc(string(PING), f)
523424
}
524425

525426
// registerEchoHandler registers a custom handler for the ECHO command
526-
// ECHO message - Return the given string
527427
func (s *Server) registerEchoHandler(f func(conn *Connection, cmd *Command) RedisValue) {
528428
s.RegisterCommandFunc(string(ECHO), f)
529429
}
530430

531431
// registerQuitHandler registers a custom handler for the QUIT command
532-
// QUIT - Close the connection
533432
func (s *Server) registerQuitHandler(f func(conn *Connection, cmd *Command) RedisValue) {
534433
s.RegisterCommandFunc(string(QUIT), f)
535434
}
536435

537436
// registerHelpHandler registers a custom handler for the HELP command
538-
// HELP - Show available commands and their descriptions
539437
func (s *Server) registerHelpHandler(f func(conn *Connection, cmd *Command) RedisValue) {
540438
s.RegisterCommandFunc(string(HELP), f)
541439
}

connection.go

Lines changed: 10 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,3 @@
1-
/*
2-
Package redkit implements client connection management for Redis-compatible servers.
3-
4-
This file provides the Connection type and associated methods for managing
5-
individual client connections throughout their lifecycle.
6-
7-
Core Responsibilities:
8-
- TCP/TLS connection wrapping and management
9-
- Buffered I/O for optimal Redis protocol performance
10-
- Thread-safe connection state tracking and transitions
11-
- Context-based cancellation and resource cleanup
12-
- Connection metadata and network address access
13-
14-
Connection Lifecycle:
15-
1. Connection creation and initialization (StateNew)
16-
2. Active command processing (StateActive)
17-
3. Idle waiting between commands (StateIdle)
18-
4. Graceful termination and cleanup (StateClosed)
19-
20-
Thread Safety:
21-
The Connection type is designed for concurrent access with proper synchronization:
22-
- Atomic operations for state management
23-
- Mutex protection for shared fields (lastUsed)
24-
- sync.Once for safe connection cleanup
25-
- Context cancellation for coordinated shutdown
26-
27-
Performance Optimizations:
28-
- Buffered readers and writers to minimize syscalls
29-
- Atomic state tracking to avoid lock contention
30-
- Efficient network address caching
31-
- Minimal allocation overhead in hot paths
32-
33-
Integration:
34-
Connection instances are typically created by the Server during client
35-
connection acceptance and managed throughout the command processing
36-
lifecycle. They provide the necessary context for command handlers
37-
to access client-specific state and network information.
38-
39-
Usage Example:
40-
41-
// Connection is typically created by the server
42-
conn := &Connection{
43-
conn: netConn,
44-
reader: bufio.NewReader(netConn),
45-
writer: bufio.NewWriter(netConn),
46-
server: server,
47-
ctx: ctx,
48-
cancel: cancelFunc,
49-
lastUsed: time.Now(),
50-
}
51-
52-
// Command handlers can access connection context
53-
func myHandler(conn *Connection, cmd *Command) RedisValue {
54-
clientAddr := conn.RemoteAddr()
55-
state := conn.GetState()
56-
// Process command with connection context
57-
}
58-
*/
591
package redkit
602

613
import (
@@ -67,67 +9,21 @@ import (
679
"time"
6810
)
6911

70-
/*
71-
Client Connection Management
72-
73-
Connection wraps a network connection with Redis protocol-specific
74-
functionality including buffered I/O, state tracking, and lifecycle management.
75-
76-
Fields Overview:
77-
- conn: Underlying TCP/TLS network connection
78-
- reader/writer: Buffered I/O for efficient Redis protocol handling
79-
- server: Reference to parent server for configuration and hooks
80-
- state: Atomic connection state (StateNew/Active/Idle/Closed)
81-
- closeOnce: Ensures connection is closed exactly once (thread-safe)
82-
- ctx/cancel: Context for coordinated cancellation and cleanup
83-
- mu: Protects shared mutable fields like lastUsed
84-
- lastUsed: Timestamp for idle timeout management
85-
86-
Thread Safety:
87-
All public methods are thread-safe and can be called concurrently
88-
from multiple goroutines. State transitions are atomic and properly
89-
synchronized with connection hooks and cleanup operations.
90-
91-
Resource Management:
92-
The Connection automatically manages its resources and integrates
93-
with the server's connection tracking for proper cleanup during
94-
shutdown scenarios.
95-
*/
96-
9712
// Connection represents a client connection to the Redis server
9813
type Connection struct {
99-
conn net.Conn // Underlying network connection
100-
reader *bufio.Reader // Buffered reader for efficient parsing
101-
writer *bufio.Writer // Buffered writer for response batching
102-
server *Server // Parent server reference
103-
state atomic.Int32 // Current connection state (atomic)
104-
closeOnce sync.Once // Ensures single cleanup execution
105-
ctx context.Context // Connection context for cancellation
106-
cancel context.CancelFunc // Context cancellation function
107-
mu sync.RWMutex // Protects mutable fields
108-
lastUsed time.Time // Last activity timestamp for idle detection
14+
conn net.Conn
15+
reader *bufio.Reader
16+
writer *bufio.Writer
17+
server *Server
18+
state atomic.Int32
19+
closeOnce sync.Once
20+
ctx context.Context
21+
cancel context.CancelFunc
22+
mu sync.RWMutex
23+
lastUsed time.Time
10924
}
11025

111-
/*
112-
Connection State Management
113-
114-
These methods manage connection state transitions and provide
115-
thread-safe access to connection status information.
116-
*/
117-
11826
// setState updates the connection state
119-
// Atomically updates the connection state and triggers the server's
120-
// connection state hook if configured. This enables monitoring and
121-
// metrics collection for connection lifecycle events.
122-
//
123-
// State transitions follow the pattern:
124-
// StateNew -> StateActive -> StateIdle -> StateClosed
125-
//
126-
// ↑ ↓
127-
// └─────────┘ (can cycle)
128-
//
129-
// Parameters:
130-
// - state: New connection state to set
13127
func (c *Connection) setState(state ConnState) {
13228
c.state.Store(int32(state))
13329
if c.server.ConnStateHook != nil {
@@ -136,17 +32,6 @@ func (c *Connection) setState(state ConnState) {
13632
}
13733

13834
// Close closes the connection
139-
// Performs thread-safe connection cleanup exactly once, regardless of
140-
// how many times it's called. The cleanup process includes:
141-
// 1. Setting connection state to StateClosed
142-
// 2. Cancelling the connection context (stops background operations)
143-
// 3. Closing the underlying network connection
144-
//
145-
// This method is safe to call multiple times and from multiple goroutines.
146-
// Subsequent calls after the first will be no-ops.
147-
//
148-
// Returns:
149-
// - error: Network connection close error, if any
15035
func (c *Connection) Close() error {
15136
var err error
15237
c.closeOnce.Do(func() {
@@ -158,40 +43,16 @@ func (c *Connection) Close() error {
15843
}
15944

16045
// GetState returns the current connection state
161-
// Thread-safe method to query the current state without triggering
162-
// any state transitions or side effects. Useful for monitoring,
163-
// logging, and conditional logic based on connection status.
164-
//
165-
// Returns:
166-
// - ConnState: Current connection state (StateNew/Active/Idle/Closed)
16746
func (c *Connection) GetState() ConnState {
16847
return ConnState(c.state.Load())
16948
}
17049

171-
/*
172-
Network Address Access
173-
174-
These methods provide access to the connection's network endpoints
175-
for logging, monitoring, and access control purposes.
176-
*/
177-
17850
// RemoteAddr returns the remote network address
179-
// Provides access to the client's network address for logging,
180-
// access control, and monitoring purposes. The address format
181-
// depends on the network type (TCP: "IP:port", Unix: socket path).
182-
//
183-
// Returns:
184-
// - net.Addr: Client's network address
18551
func (c *Connection) RemoteAddr() net.Addr {
18652
return c.conn.RemoteAddr()
18753
}
18854

18955
// LocalAddr returns the local network address
190-
// Provides access to the server's local address that accepted
191-
// this connection. Useful for multi-interface servers and logging.
192-
//
193-
// Returns:
194-
// - net.Addr: Server's local network address for this connection
19556
func (c *Connection) LocalAddr() net.Addr {
19657
return c.conn.LocalAddr()
19758
}

0 commit comments

Comments
 (0)