@@ -25,7 +25,7 @@ const (
25
25
var errConnLost = errors .New ("redis: connection lost while awaiting response" )
26
26
27
27
// ClientConfig defines a Client setup.
28
- type ClientConfig struct {
28
+ type ClientConfig [ Key , Value String ] struct {
29
29
// The host defaults to localhost, and the port defaults to 6379.
30
30
// Thus, the empty string defaults to "localhost:6379". Use an
31
31
// absolute file path (e.g. "/var/run/redis.sock") for Unix
@@ -53,7 +53,7 @@ type ClientConfig struct {
53
53
}
54
54
55
55
// NewClient launches a managed connection to a node (address).
56
- func (c * ClientConfig ) NewClient () * Client {
56
+ func (c * ClientConfig [ Key , Value ] ) NewClient () * Client [ Key , Value ] {
57
57
return newClient (* c )
58
58
}
59
59
@@ -62,11 +62,11 @@ func (c *ClientConfig) NewClient() *Client {
62
62
//
63
63
// Multiple goroutines may invoke methods on a Client simultaneously. Command
64
64
// invocation applies <https://redis.io/topics/pipelining> on concurrency.
65
- type Client struct {
65
+ type Client [ Key , Value String ] struct {
66
66
// Normalized node address in use. This field is read-only.
67
67
Addr string
68
68
69
- config ClientConfig
69
+ config ClientConfig [ Key , Value ]
70
70
71
71
noCopy noCopy
72
72
@@ -100,15 +100,15 @@ type Client struct {
100
100
// submission blocks on the first attempt. When connection establishment fails,
101
101
// then command submission receives the error of the last attempt, until the
102
102
// connection restores.
103
- func NewClient (addr string , commandTimeout , dialTimeout time.Duration ) * Client {
104
- return newClient (ClientConfig {
103
+ func NewClient [ Key , Value String ] (addr string , commandTimeout , dialTimeout time.Duration ) * Client [ Key , Value ] {
104
+ return newClient (ClientConfig [ Key , Value ] {
105
105
Addr : addr ,
106
106
CommandTimeout : commandTimeout ,
107
107
DialTimeout : dialTimeout ,
108
108
})
109
109
}
110
110
111
- func newClient (config ClientConfig ) * Client {
111
+ func newClient [ Key , Value String ] (config ClientConfig [ Key , Value ] ) * Client [ Key , Value ] {
112
112
config .Addr = normalizeAddr (config .Addr )
113
113
if config .DialTimeout == 0 {
114
114
config .DialTimeout = time .Second
@@ -119,7 +119,7 @@ func newClient(config ClientConfig) *Client {
119
119
queueSize = queueSizeUnix
120
120
}
121
121
122
- c := & Client {
122
+ c := & Client [ Key , Value ] {
123
123
Addr : config .Addr , // decouple
124
124
config : config ,
125
125
@@ -145,7 +145,7 @@ type redisConn struct {
145
145
// Command submission is stopped with ErrClosed.
146
146
// All pending commands are dealt with on return.
147
147
// Calling Close more than once has no effect.
148
- func (c * Client ) Close () error {
148
+ func (c * Client [ Key , Value ] ) Close () error {
149
149
conn := <- c .connSem // lock write
150
150
if conn .offline == ErrClosed {
151
151
// redundant invocation
@@ -170,7 +170,7 @@ func (c *Client) Close() error {
170
170
}
171
171
172
172
// connectOrClosed populates the connection semaphore.
173
- func (c * Client ) connectOrClosed () {
173
+ func (c * Client [ Key , Value ] ) connectOrClosed () {
174
174
var retryDelay time.Duration
175
175
for {
176
176
conn , reader , err := c .config .connect (conservativeMSS )
@@ -213,7 +213,7 @@ func (c *Client) connectOrClosed() {
213
213
}
214
214
}
215
215
216
- func (c * Client ) cancelQueue () {
216
+ func (c * Client [ Key , Value ] ) cancelQueue () {
217
217
for {
218
218
select {
219
219
case ch := <- c .readQueue :
@@ -227,7 +227,7 @@ func (c *Client) cancelQueue() {
227
227
228
228
// Exchange sends a request, and then it awaits its turn (in the pipeline) for
229
229
// response receiption.
230
- func (c * Client ) exchange (req * request ) (* bufio.Reader , error ) {
230
+ func (c * Client [ Key , Value ] ) exchange (req * request ) (* bufio.Reader , error ) {
231
231
conn := <- c .connSem // lock write
232
232
233
233
// validate connection state
@@ -290,7 +290,7 @@ func (c *Client) exchange(req *request) (*bufio.Reader, error) {
290
290
return reader , nil
291
291
}
292
292
293
- func (c * Client ) commandOK (req * request ) error {
293
+ func (c * Client [ Key , Value ] ) commandOK (req * request ) error {
294
294
r , err := c .exchange (req )
295
295
if err != nil {
296
296
return err
@@ -300,7 +300,7 @@ func (c *Client) commandOK(req *request) error {
300
300
return err
301
301
}
302
302
303
- func (c * Client ) commandOKOrReconnect (req * request ) error {
303
+ func (c * Client [ Key , Value ] ) commandOKOrReconnect (req * request ) error {
304
304
r , err := c .exchange (req )
305
305
if err != nil {
306
306
return err
@@ -314,7 +314,7 @@ func (c *Client) commandOKOrReconnect(req *request) error {
314
314
return err
315
315
}
316
316
317
- func (c * Client ) commandInteger (req * request ) (int64 , error ) {
317
+ func (c * Client [ Key , Value ] ) commandInteger (req * request ) (int64 , error ) {
318
318
r , err := c .exchange (req )
319
319
if err != nil {
320
320
return 0 , err
@@ -324,62 +324,36 @@ func (c *Client) commandInteger(req *request) (int64, error) {
324
324
return integer , err
325
325
}
326
326
327
- func (c * Client ) commandBulkBytes (req * request ) ([] byte , error ) {
327
+ func (c * Client [ Key , Value ]) commandBulk (req * request ) (bulk Value , _ error ) {
328
328
r , err := c .exchange (req )
329
329
if err != nil {
330
- return nil , err
331
- }
332
- bytes , err := readBulkBytes (r )
333
- c .passRead (r , err )
334
- if err == errNull {
335
- return nil , nil
336
- }
337
- return bytes , err
338
- }
339
-
340
- func (c * Client ) commandBulkString (req * request ) (string , bool , error ) {
341
- r , err := c .exchange (req )
342
- if err != nil {
343
- return "" , false , err
330
+ return bulk , err
344
331
}
345
- s , err := readBulkString (r )
332
+ bulk , err = readBulk [ Value ] (r )
346
333
c .passRead (r , err )
347
334
if err == errNull {
348
- return "" , false , nil
335
+ err = nil
349
336
}
350
- return s , true , err
351
- }
352
-
353
- func (c * Client ) commandBytesArray (req * request ) ([][]byte , error ) {
354
- r , err := c .exchange (req )
355
- if err != nil {
356
- return nil , err
357
- }
358
- array , err := readBytesArray (r )
359
- c .passRead (r , err )
360
- if err == errNull {
361
- return nil , nil
362
- }
363
- return array , err
337
+ return bulk , err
364
338
}
365
339
366
- func (c * Client ) commandStringArray (req * request ) ([]string , error ) {
340
+ func (c * Client [ Key , Value ]) commandArray (req * request ) ([]Value , error ) {
367
341
r , err := c .exchange (req )
368
342
if err != nil {
369
343
return nil , err
370
344
}
371
- array , err := readStringArray (r )
345
+ array , err := readArray [ Value ] (r )
372
346
c .passRead (r , err )
373
347
if err == errNull {
374
- return nil , nil
348
+ err = nil
375
349
}
376
350
return array , err
377
351
}
378
352
379
353
// PassRead hands over the buffered reader to the following command in line. It
380
354
// goes in idle mode (on the redisConn from connSem) when all requests are done
381
355
// for.
382
- func (c * Client ) passRead (r * bufio.Reader , err error ) {
356
+ func (c * Client [ Key , Value ] ) passRead (r * bufio.Reader , err error ) {
383
357
switch err {
384
358
case nil , errNull :
385
359
break
@@ -426,7 +400,7 @@ func (c *Client) passRead(r *bufio.Reader, err error) {
426
400
}
427
401
428
402
// DropConnFromRead disconnects with Redis.
429
- func (c * Client ) dropConnFromRead () {
403
+ func (c * Client [ Key , Value ] ) dropConnFromRead () {
430
404
for {
431
405
select {
432
406
case <- c .readTerm :
@@ -457,7 +431,7 @@ func (c *Client) dropConnFromRead() {
457
431
}
458
432
}
459
433
460
- func (c * ClientConfig ) connect (readBufferSize int ) (net.Conn , * bufio.Reader , error ) {
434
+ func (c * ClientConfig [ Key , Value ] ) connect (readBufferSize int ) (net.Conn , * bufio.Reader , error ) {
461
435
network := "tcp"
462
436
if isUnixAddr (c .Addr ) {
463
437
network = "unix"
0 commit comments