作者 唐旭辉
正在显示 26 个修改的文件 包含 229 行增加135 行删除
  1 +package common
  2 +
  3 +import "testing"
  4 +
  5 +func Test_Jwt(t *testing.T){
  6 +
  7 +}
@@ -7,9 +7,9 @@ require ( @@ -7,9 +7,9 @@ require (
7 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect 7 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
8 8
9 github.com/dgrijalva/jwt-go v3.2.0+incompatible 9 github.com/dgrijalva/jwt-go v3.2.0+incompatible
10 - github.com/garyburd/redigo v1.6.0  
11 github.com/gin-gonic/gin v1.4.0 10 github.com/gin-gonic/gin v1.4.0
12 github.com/go-sql-driver/mysql v1.4.1 // indirect 11 github.com/go-sql-driver/mysql v1.4.1 // indirect
  12 + github.com/gomodule/redigo v1.7.0
13 github.com/google/go-cmp v0.2.0 13 github.com/google/go-cmp v0.2.0
14 github.com/gorilla/websocket v1.4.1 14 github.com/gorilla/websocket v1.4.1
15 github.com/lib/pq v1.2.0 // indirect 15 github.com/lib/pq v1.2.0 // indirect
@@ -189,6 +189,12 @@ func (u UUID) String() string { @@ -189,6 +189,12 @@ func (u UUID) String() string {
189 return string(buf) 189 return string(buf)
190 } 190 }
191 191
  192 +func (u UUID) StringNoDash() string {
  193 + buf := make([]byte, 32)
  194 + hex.Encode(buf, u[0:])
  195 + return string(buf)
  196 +}
  197 +
192 //0001 时间的版本 198 //0001 时间的版本
193 //0010 DCE Security 199 //0010 DCE Security
194 //0011 MD5哈希 200 //0011 MD5哈希
@@ -2,6 +2,7 @@ package uid @@ -2,6 +2,7 @@ package uid
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "strings"
5 "testing" 6 "testing"
6 ) 7 )
7 8
@@ -15,4 +16,39 @@ func TestUID(t *testing.T){ @@ -15,4 +16,39 @@ func TestUID(t *testing.T){
15 } 16 }
16 fmt.Println("MarshalBinary:",udata) 17 fmt.Println("MarshalBinary:",udata)
17 fmt.Println("uuid version:",uid.Version()) 18 fmt.Println("uuid version:",uid.Version())
  19 +
  20 + uidStr36 :=uid.String()
  21 + uidStr32 :=uid.StringNoDash()
  22 + if strings.Replace(uidStr36,"-","",-1) != uidStr32{
  23 + t.Fatal("no equal",uidStr36,uidStr32)
  24 + }
  25 + t.Log(uidStr36,uidStr32)
  26 +}
  27 +
  28 +func Test_StringNoDash(t *testing.T){
  29 + for i:=0;i<100;i++{
  30 + uid :=NewV1()
  31 + uidStr36 :=uid.String()
  32 + uidStr32 :=uid.StringNoDash()
  33 + if strings.Replace(uidStr36,"-","",-1) != uidStr32{
  34 + t.Fatal("no equal",uidStr36,uidStr32)
  35 + }
  36 + }
  37 +}
  38 +
  39 +func Test_NewV1(t *testing.T){
  40 + num :=10000
  41 + mUid :=make(map[string]int,num)
  42 + for i:=0;i<num;i++{
  43 + uid :=NewV1()
  44 + uidStr36 :=uid.String()
  45 + if _,ok:=mUid[uidStr36];ok{
  46 + t.Fatal("repeat uid",uidStr36)
  47 + }else{
  48 + mUid[uidStr36]=0
  49 + }
  50 + }
  51 + if len(mUid)!=num{
  52 + t.Fatal("map num error")
  53 + }
18 } 54 }
@@ -2,7 +2,7 @@ package redis @@ -2,7 +2,7 @@ package redis
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 - "github.com/garyburd/redigo/redis" 5 + "github.com/gomodule/redigo/redis"
6 ) 6 )
7 7
8 //设置指定hash指定key的值 8 //设置指定hash指定key的值
@@ -3,7 +3,7 @@ package redis @@ -3,7 +3,7 @@ package redis
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "github.com/astaxie/beego" 5 "github.com/astaxie/beego"
6 - "github.com/garyburd/redigo/redis" 6 + "github.com/gomodule/redigo/redis"
7 "sync" 7 "sync"
8 ) 8 )
9 9
@@ -3,7 +3,7 @@ package redis @@ -3,7 +3,7 @@ package redis
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 - "github.com/garyburd/redigo/redis" 6 + "github.com/gomodule/redigo/redis"
7 "gitlab.fjmaimaimai.com/mmm-go/gocomm/config" 7 "gitlab.fjmaimaimai.com/mmm-go/gocomm/config"
8 "time" 8 "time"
9 ) 9 )
@@ -2,8 +2,7 @@ package redis @@ -2,8 +2,7 @@ package redis
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 -  
6 - "github.com/garyburd/redigo/redis" 5 + "github.com/gomodule/redigo/redis"
7 ) 6 )
8 7
9 //设置集合 8 //设置集合
@@ -3,8 +3,7 @@ package redis @@ -3,8 +3,7 @@ package redis
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "errors" 5 "errors"
6 -  
7 - "github.com/garyburd/redigo/redis" 6 + "github.com/gomodule/redigo/redis"
8 ) 7 )
9 8
10 func Set(key string, v interface{}, timeout int64) error { 9 func Set(key string, v interface{}, timeout int64) error {
@@ -2,7 +2,7 @@ package redis @@ -2,7 +2,7 @@ package redis
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 - "github.com/garyburd/redigo/redis" 5 + "github.com/gomodule/redigo/redis"
6 ) 6 )
7 7
8 //设置集合 8 //设置集合
@@ -12,32 +12,33 @@ @@ -12,32 +12,33 @@
12 // License for the specific language governing permissions and limitations 12 // License for the specific language governing permissions and limitations
13 // under the License. 13 // under the License.
14 14
15 -package internal // import "github.com/garyburd/redigo/internal" 15 +package redis
16 16
17 import ( 17 import (
18 "strings" 18 "strings"
19 ) 19 )
20 20
21 const ( 21 const (
22 - WatchState = 1 << iota  
23 - MultiState  
24 - SubscribeState  
25 - MonitorState 22 + connectionWatchState = 1 << iota
  23 + connectionMultiState
  24 + connectionSubscribeState
  25 + connectionMonitorState
26 ) 26 )
27 27
28 -type CommandInfo struct { 28 +type commandInfo struct {
  29 + // Set or Clear these states on connection.
29 Set, Clear int 30 Set, Clear int
30 } 31 }
31 32
32 -var commandInfos = map[string]CommandInfo{  
33 - "WATCH": {Set: WatchState},  
34 - "UNWATCH": {Clear: WatchState},  
35 - "MULTI": {Set: MultiState},  
36 - "EXEC": {Clear: WatchState | MultiState},  
37 - "DISCARD": {Clear: WatchState | MultiState},  
38 - "PSUBSCRIBE": {Set: SubscribeState},  
39 - "SUBSCRIBE": {Set: SubscribeState},  
40 - "MONITOR": {Set: MonitorState}, 33 +var commandInfos = map[string]commandInfo{
  34 + "WATCH": {Set: connectionWatchState},
  35 + "UNWATCH": {Clear: connectionWatchState},
  36 + "MULTI": {Set: connectionMultiState},
  37 + "EXEC": {Clear: connectionWatchState | connectionMultiState},
  38 + "DISCARD": {Clear: connectionWatchState | connectionMultiState},
  39 + "PSUBSCRIBE": {Set: connectionSubscribeState},
  40 + "SUBSCRIBE": {Set: connectionSubscribeState},
  41 + "MONITOR": {Set: connectionMonitorState},
41 } 42 }
42 43
43 func init() { 44 func init() {
@@ -46,7 +47,7 @@ func init() { @@ -46,7 +47,7 @@ func init() {
46 } 47 }
47 } 48 }
48 49
49 -func LookupCommandInfo(commandName string) CommandInfo { 50 +func lookupCommandInfo(commandName string) commandInfo {
50 if ci, ok := commandInfos[commandName]; ok { 51 if ci, ok := commandInfos[commandName]; ok {
51 return ci 52 return ci
52 } 53 }
@@ -427,10 +427,21 @@ func (pe protocolError) Error() string { @@ -427,10 +427,21 @@ func (pe protocolError) Error() string {
427 return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe)) 427 return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
428 } 428 }
429 429
  430 +// readLine reads a line of input from the RESP stream.
430 func (c *conn) readLine() ([]byte, error) { 431 func (c *conn) readLine() ([]byte, error) {
  432 + // To avoid allocations, attempt to read the line using ReadSlice. This
  433 + // call typically succeeds. The known case where the call fails is when
  434 + // reading the output from the MONITOR command.
431 p, err := c.br.ReadSlice('\n') 435 p, err := c.br.ReadSlice('\n')
432 if err == bufio.ErrBufferFull { 436 if err == bufio.ErrBufferFull {
433 - return nil, protocolError("long response line") 437 + // The line does not fit in the bufio.Reader's buffer. Fall back to
  438 + // allocating a buffer for the line.
  439 + buf := append([]byte{}, p...)
  440 + for err == bufio.ErrBufferFull {
  441 + p, err = c.br.ReadSlice('\n')
  442 + buf = append(buf, p...)
  443 + }
  444 + p = buf
434 } 445 }
435 if err != nil { 446 if err != nil {
436 return nil, err 447 return nil, err
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 14
15 // Package redis is a client for the Redis database. 15 // Package redis is a client for the Redis database.
16 // 16 //
17 -// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more 17 +// The Redigo FAQ (https://github.com/gomodule/redigo/wiki/FAQ) contains more
18 // documentation about this package. 18 // documentation about this package.
19 // 19 //
20 // Connections 20 // Connections
@@ -174,4 +174,4 @@ @@ -174,4 +174,4 @@
174 // non-recoverable error such as a network error or protocol parsing error. If 174 // non-recoverable error such as a network error or protocol parsing error. If
175 // Err() returns a non-nil value, then the connection is not usable and should 175 // Err() returns a non-nil value, then the connection is not usable and should
176 // be closed. 176 // be closed.
177 -package redis // import "github.com/garyburd/redigo/redis" 177 +package redis
@@ -30,13 +30,22 @@ func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn { @@ -30,13 +30,22 @@ func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
30 if prefix != "" { 30 if prefix != "" {
31 prefix = prefix + "." 31 prefix = prefix + "."
32 } 32 }
33 - return &loggingConn{conn, logger, prefix} 33 + return &loggingConn{conn, logger, prefix, nil}
  34 +}
  35 +
  36 +//NewLoggingConnFilter returns a logging wrapper around a connection and a filter function.
  37 +func NewLoggingConnFilter(conn Conn, logger *log.Logger, prefix string, skip func(cmdName string) bool) Conn {
  38 + if prefix != "" {
  39 + prefix = prefix + "."
  40 + }
  41 + return &loggingConn{conn, logger, prefix, skip}
34 } 42 }
35 43
36 type loggingConn struct { 44 type loggingConn struct {
37 Conn 45 Conn
38 logger *log.Logger 46 logger *log.Logger
39 prefix string 47 prefix string
  48 + skip func(cmdName string) bool
40 } 49 }
41 50
42 func (c *loggingConn) Close() error { 51 func (c *loggingConn) Close() error {
@@ -85,6 +94,9 @@ func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) { @@ -85,6 +94,9 @@ func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
85 } 94 }
86 95
87 func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) { 96 func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
  97 + if c.skip != nil && c.skip(commandName) {
  98 + return
  99 + }
88 var buf bytes.Buffer 100 var buf bytes.Buffer
89 fmt.Fprintf(&buf, "%s%s(", c.prefix, method) 101 fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
90 if method != "Receive" { 102 if method != "Receive" {
@@ -24,13 +24,11 @@ import ( @@ -24,13 +24,11 @@ import (
24 "sync" 24 "sync"
25 "sync/atomic" 25 "sync/atomic"
26 "time" 26 "time"
27 -  
28 - "github.com/garyburd/redigo/internal"  
29 ) 27 )
30 28
31 var ( 29 var (
32 - _ ConnWithTimeout = (*pooledConnection)(nil)  
33 - _ ConnWithTimeout = (*errorConnection)(nil) 30 + _ ConnWithTimeout = (*activeConn)(nil)
  31 + _ ConnWithTimeout = (*errorConn)(nil)
34 ) 32 )
35 33
36 var nowFunc = time.Now // for testing 34 var nowFunc = time.Now // for testing
@@ -150,6 +148,10 @@ type Pool struct { @@ -150,6 +148,10 @@ type Pool struct {
150 // for a connection to be returned to the pool before returning. 148 // for a connection to be returned to the pool before returning.
151 Wait bool 149 Wait bool
152 150
  151 + // Close connections older than this duration. If the value is zero, then
  152 + // the pool does not close connections based on age.
  153 + MaxConnLifetime time.Duration
  154 +
153 chInitialized uint32 // set to 1 when field ch is initialized 155 chInitialized uint32 // set to 1 when field ch is initialized
154 156
155 mu sync.Mutex // mu protects the following fields 157 mu sync.Mutex // mu protects the following fields
@@ -172,11 +174,11 @@ func NewPool(newFn func() (Conn, error), maxIdle int) *Pool { @@ -172,11 +174,11 @@ func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
172 // getting an underlying connection, then the connection Err, Do, Send, Flush 174 // getting an underlying connection, then the connection Err, Do, Send, Flush
173 // and Receive methods return that error. 175 // and Receive methods return that error.
174 func (p *Pool) Get() Conn { 176 func (p *Pool) Get() Conn {
175 - c, err := p.get(nil) 177 + pc, err := p.get(nil)
176 if err != nil { 178 if err != nil {
177 - return errorConnection{err} 179 + return errorConn{err}
178 } 180 }
179 - return &pooledConnection{p: p, c: c} 181 + return &activeConn{p: p, pc: pc}
180 } 182 }
181 183
182 // PoolStats contains pool statistics. 184 // PoolStats contains pool statistics.
@@ -226,15 +228,15 @@ func (p *Pool) Close() error { @@ -226,15 +228,15 @@ func (p *Pool) Close() error {
226 } 228 }
227 p.closed = true 229 p.closed = true
228 p.active -= p.idle.count 230 p.active -= p.idle.count
229 - ic := p.idle.front 231 + pc := p.idle.front
230 p.idle.count = 0 232 p.idle.count = 0
231 p.idle.front, p.idle.back = nil, nil 233 p.idle.front, p.idle.back = nil, nil
232 if p.ch != nil { 234 if p.ch != nil {
233 close(p.ch) 235 close(p.ch)
234 } 236 }
235 p.mu.Unlock() 237 p.mu.Unlock()
236 - for ; ic != nil; ic = ic.next {  
237 - ic.c.Close() 238 + for ; pc != nil; pc = pc.next {
  239 + pc.c.Close()
238 } 240 }
239 return nil 241 return nil
240 } 242 }
@@ -265,7 +267,7 @@ func (p *Pool) lazyInit() { @@ -265,7 +267,7 @@ func (p *Pool) lazyInit() {
265 func (p *Pool) get(ctx interface { 267 func (p *Pool) get(ctx interface {
266 Done() <-chan struct{} 268 Done() <-chan struct{}
267 Err() error 269 Err() error
268 -}) (Conn, error) { 270 +}) (*poolConn, error) {
269 271
270 // Handle limit for p.Wait == true. 272 // Handle limit for p.Wait == true.
271 if p.Wait && p.MaxActive > 0 { 273 if p.Wait && p.MaxActive > 0 {
@@ -287,10 +289,10 @@ func (p *Pool) get(ctx interface { @@ -287,10 +289,10 @@ func (p *Pool) get(ctx interface {
287 if p.IdleTimeout > 0 { 289 if p.IdleTimeout > 0 {
288 n := p.idle.count 290 n := p.idle.count
289 for i := 0; i < n && p.idle.back != nil && p.idle.back.t.Add(p.IdleTimeout).Before(nowFunc()); i++ { 291 for i := 0; i < n && p.idle.back != nil && p.idle.back.t.Add(p.IdleTimeout).Before(nowFunc()); i++ {
290 - c := p.idle.back.c 292 + pc := p.idle.back
291 p.idle.popBack() 293 p.idle.popBack()
292 p.mu.Unlock() 294 p.mu.Unlock()
293 - c.Close() 295 + pc.c.Close()
294 p.mu.Lock() 296 p.mu.Lock()
295 p.active-- 297 p.active--
296 } 298 }
@@ -298,13 +300,14 @@ func (p *Pool) get(ctx interface { @@ -298,13 +300,14 @@ func (p *Pool) get(ctx interface {
298 300
299 // Get idle connection from the front of idle list. 301 // Get idle connection from the front of idle list.
300 for p.idle.front != nil { 302 for p.idle.front != nil {
301 - ic := p.idle.front 303 + pc := p.idle.front
302 p.idle.popFront() 304 p.idle.popFront()
303 p.mu.Unlock() 305 p.mu.Unlock()
304 - if p.TestOnBorrow == nil || p.TestOnBorrow(ic.c, ic.t) == nil {  
305 - return ic.c, nil 306 + if (p.TestOnBorrow == nil || p.TestOnBorrow(pc.c, pc.t) == nil) &&
  307 + (p.MaxConnLifetime == 0 || nowFunc().Sub(pc.created) < p.MaxConnLifetime) {
  308 + return pc, nil
306 } 309 }
307 - ic.c.Close() 310 + pc.c.Close()
308 p.mu.Lock() 311 p.mu.Lock()
309 p.active-- 312 p.active--
310 } 313 }
@@ -333,24 +336,25 @@ func (p *Pool) get(ctx interface { @@ -333,24 +336,25 @@ func (p *Pool) get(ctx interface {
333 } 336 }
334 p.mu.Unlock() 337 p.mu.Unlock()
335 } 338 }
336 - return c, err 339 + return &poolConn{c: c, created: nowFunc()}, err
337 } 340 }
338 341
339 -func (p *Pool) put(c Conn, forceClose bool) error { 342 +func (p *Pool) put(pc *poolConn, forceClose bool) error {
340 p.mu.Lock() 343 p.mu.Lock()
341 if !p.closed && !forceClose { 344 if !p.closed && !forceClose {
342 - p.idle.pushFront(&idleConn{t: nowFunc(), c: c}) 345 + pc.t = nowFunc()
  346 + p.idle.pushFront(pc)
343 if p.idle.count > p.MaxIdle { 347 if p.idle.count > p.MaxIdle {
344 - c = p.idle.back.c 348 + pc = p.idle.back
345 p.idle.popBack() 349 p.idle.popBack()
346 } else { 350 } else {
347 - c = nil 351 + pc = nil
348 } 352 }
349 } 353 }
350 354
351 - if c != nil { 355 + if pc != nil {
352 p.mu.Unlock() 356 p.mu.Unlock()
353 - c.Close() 357 + pc.c.Close()
354 p.mu.Lock() 358 p.mu.Lock()
355 p.active-- 359 p.active--
356 } 360 }
@@ -362,9 +366,9 @@ func (p *Pool) put(c Conn, forceClose bool) error { @@ -362,9 +366,9 @@ func (p *Pool) put(c Conn, forceClose bool) error {
362 return nil 366 return nil
363 } 367 }
364 368
365 -type pooledConnection struct { 369 +type activeConn struct {
366 p *Pool 370 p *Pool
367 - c Conn 371 + pc *poolConn
368 state int 372 state int
369 } 373 }
370 374
@@ -385,79 +389,107 @@ func initSentinel() { @@ -385,79 +389,107 @@ func initSentinel() {
385 } 389 }
386 } 390 }
387 391
388 -func (pc *pooledConnection) Close() error {  
389 - c := pc.c  
390 - if _, ok := c.(errorConnection); ok { 392 +func (ac *activeConn) Close() error {
  393 + pc := ac.pc
  394 + if pc == nil {
391 return nil 395 return nil
392 } 396 }
393 - pc.c = errorConnection{errConnClosed} 397 + ac.pc = nil
394 398
395 - if pc.state&internal.MultiState != 0 {  
396 - c.Send("DISCARD")  
397 - pc.state &^= (internal.MultiState | internal.WatchState)  
398 - } else if pc.state&internal.WatchState != 0 {  
399 - c.Send("UNWATCH")  
400 - pc.state &^= internal.WatchState 399 + if ac.state&connectionMultiState != 0 {
  400 + pc.c.Send("DISCARD")
  401 + ac.state &^= (connectionMultiState | connectionWatchState)
  402 + } else if ac.state&connectionWatchState != 0 {
  403 + pc.c.Send("UNWATCH")
  404 + ac.state &^= connectionWatchState
401 } 405 }
402 - if pc.state&internal.SubscribeState != 0 {  
403 - c.Send("UNSUBSCRIBE")  
404 - c.Send("PUNSUBSCRIBE") 406 + if ac.state&connectionSubscribeState != 0 {
  407 + pc.c.Send("UNSUBSCRIBE")
  408 + pc.c.Send("PUNSUBSCRIBE")
405 // To detect the end of the message stream, ask the server to echo 409 // To detect the end of the message stream, ask the server to echo
406 // a sentinel value and read until we see that value. 410 // a sentinel value and read until we see that value.
407 sentinelOnce.Do(initSentinel) 411 sentinelOnce.Do(initSentinel)
408 - c.Send("ECHO", sentinel)  
409 - c.Flush() 412 + pc.c.Send("ECHO", sentinel)
  413 + pc.c.Flush()
410 for { 414 for {
411 - p, err := c.Receive() 415 + p, err := pc.c.Receive()
412 if err != nil { 416 if err != nil {
413 break 417 break
414 } 418 }
415 if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) { 419 if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
416 - pc.state &^= internal.SubscribeState 420 + ac.state &^= connectionSubscribeState
417 break 421 break
418 } 422 }
419 } 423 }
420 } 424 }
421 - c.Do("")  
422 - pc.p.put(c, pc.state != 0 || c.Err() != nil) 425 + pc.c.Do("")
  426 + ac.p.put(pc, ac.state != 0 || pc.c.Err() != nil)
423 return nil 427 return nil
424 } 428 }
425 429
426 -func (pc *pooledConnection) Err() error { 430 +func (ac *activeConn) Err() error {
  431 + pc := ac.pc
  432 + if pc == nil {
  433 + return errConnClosed
  434 + }
427 return pc.c.Err() 435 return pc.c.Err()
428 } 436 }
429 437
430 -func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) {  
431 - ci := internal.LookupCommandInfo(commandName)  
432 - pc.state = (pc.state | ci.Set) &^ ci.Clear 438 +func (ac *activeConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
  439 + pc := ac.pc
  440 + if pc == nil {
  441 + return nil, errConnClosed
  442 + }
  443 + ci := lookupCommandInfo(commandName)
  444 + ac.state = (ac.state | ci.Set) &^ ci.Clear
433 return pc.c.Do(commandName, args...) 445 return pc.c.Do(commandName, args...)
434 } 446 }
435 447
436 -func (pc *pooledConnection) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) { 448 +func (ac *activeConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
  449 + pc := ac.pc
  450 + if pc == nil {
  451 + return nil, errConnClosed
  452 + }
437 cwt, ok := pc.c.(ConnWithTimeout) 453 cwt, ok := pc.c.(ConnWithTimeout)
438 if !ok { 454 if !ok {
439 return nil, errTimeoutNotSupported 455 return nil, errTimeoutNotSupported
440 } 456 }
441 - ci := internal.LookupCommandInfo(commandName)  
442 - pc.state = (pc.state | ci.Set) &^ ci.Clear 457 + ci := lookupCommandInfo(commandName)
  458 + ac.state = (ac.state | ci.Set) &^ ci.Clear
443 return cwt.DoWithTimeout(timeout, commandName, args...) 459 return cwt.DoWithTimeout(timeout, commandName, args...)
444 } 460 }
445 461
446 -func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {  
447 - ci := internal.LookupCommandInfo(commandName)  
448 - pc.state = (pc.state | ci.Set) &^ ci.Clear 462 +func (ac *activeConn) Send(commandName string, args ...interface{}) error {
  463 + pc := ac.pc
  464 + if pc == nil {
  465 + return errConnClosed
  466 + }
  467 + ci := lookupCommandInfo(commandName)
  468 + ac.state = (ac.state | ci.Set) &^ ci.Clear
449 return pc.c.Send(commandName, args...) 469 return pc.c.Send(commandName, args...)
450 } 470 }
451 471
452 -func (pc *pooledConnection) Flush() error { 472 +func (ac *activeConn) Flush() error {
  473 + pc := ac.pc
  474 + if pc == nil {
  475 + return errConnClosed
  476 + }
453 return pc.c.Flush() 477 return pc.c.Flush()
454 } 478 }
455 479
456 -func (pc *pooledConnection) Receive() (reply interface{}, err error) { 480 +func (ac *activeConn) Receive() (reply interface{}, err error) {
  481 + pc := ac.pc
  482 + if pc == nil {
  483 + return nil, errConnClosed
  484 + }
457 return pc.c.Receive() 485 return pc.c.Receive()
458 } 486 }
459 487
460 -func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) { 488 +func (ac *activeConn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
  489 + pc := ac.pc
  490 + if pc == nil {
  491 + return nil, errConnClosed
  492 + }
461 cwt, ok := pc.c.(ConnWithTimeout) 493 cwt, ok := pc.c.(ConnWithTimeout)
462 if !ok { 494 if !ok {
463 return nil, errTimeoutNotSupported 495 return nil, errTimeoutNotSupported
@@ -465,63 +497,64 @@ func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply int @@ -465,63 +497,64 @@ func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply int
465 return cwt.ReceiveWithTimeout(timeout) 497 return cwt.ReceiveWithTimeout(timeout)
466 } 498 }
467 499
468 -type errorConnection struct{ err error } 500 +type errorConn struct{ err error }
469 501
470 -func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }  
471 -func (ec errorConnection) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) { 502 +func (ec errorConn) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
  503 +func (ec errorConn) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
472 return nil, ec.err 504 return nil, ec.err
473 } 505 }
474 -func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }  
475 -func (ec errorConnection) Err() error { return ec.err }  
476 -func (ec errorConnection) Close() error { return nil }  
477 -func (ec errorConnection) Flush() error { return ec.err }  
478 -func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }  
479 -func (ec errorConnection) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err } 506 +func (ec errorConn) Send(string, ...interface{}) error { return ec.err }
  507 +func (ec errorConn) Err() error { return ec.err }
  508 +func (ec errorConn) Close() error { return nil }
  509 +func (ec errorConn) Flush() error { return ec.err }
  510 +func (ec errorConn) Receive() (interface{}, error) { return nil, ec.err }
  511 +func (ec errorConn) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
480 512
481 type idleList struct { 513 type idleList struct {
482 count int 514 count int
483 - front, back *idleConn 515 + front, back *poolConn
484 } 516 }
485 517
486 -type idleConn struct { 518 +type poolConn struct {
487 c Conn 519 c Conn
488 t time.Time 520 t time.Time
489 - next, prev *idleConn 521 + created time.Time
  522 + next, prev *poolConn
490 } 523 }
491 524
492 -func (l *idleList) pushFront(ic *idleConn) {  
493 - ic.next = l.front  
494 - ic.prev = nil 525 +func (l *idleList) pushFront(pc *poolConn) {
  526 + pc.next = l.front
  527 + pc.prev = nil
495 if l.count == 0 { 528 if l.count == 0 {
496 - l.back = ic 529 + l.back = pc
497 } else { 530 } else {
498 - l.front.prev = ic 531 + l.front.prev = pc
499 } 532 }
500 - l.front = ic 533 + l.front = pc
501 l.count++ 534 l.count++
502 return 535 return
503 } 536 }
504 537
505 func (l *idleList) popFront() { 538 func (l *idleList) popFront() {
506 - ic := l.front 539 + pc := l.front
507 l.count-- 540 l.count--
508 if l.count == 0 { 541 if l.count == 0 {
509 l.front, l.back = nil, nil 542 l.front, l.back = nil, nil
510 } else { 543 } else {
511 - ic.next.prev = nil  
512 - l.front = ic.next 544 + pc.next.prev = nil
  545 + l.front = pc.next
513 } 546 }
514 - ic.next, ic.prev = nil, nil 547 + pc.next, pc.prev = nil, nil
515 } 548 }
516 549
517 func (l *idleList) popBack() { 550 func (l *idleList) popBack() {
518 - ic := l.back 551 + pc := l.back
519 l.count-- 552 l.count--
520 if l.count == 0 { 553 if l.count == 0 {
521 l.front, l.back = nil, nil 554 l.front, l.back = nil, nil
522 } else { 555 } else {
523 - ic.prev.next = nil  
524 - l.back = ic.prev 556 + pc.prev.next = nil
  557 + l.back = pc.prev
525 } 558 }
526 - ic.next, ic.prev = nil, nil 559 + pc.next, pc.prev = nil, nil
527 } 560 }
@@ -27,9 +27,9 @@ import "context" @@ -27,9 +27,9 @@ import "context"
27 // If the function completes without error, then the application must close the 27 // If the function completes without error, then the application must close the
28 // returned connection. 28 // returned connection.
29 func (p *Pool) GetContext(ctx context.Context) (Conn, error) { 29 func (p *Pool) GetContext(ctx context.Context) (Conn, error) {
30 - c, err := p.get(ctx) 30 + pc, err := p.get(ctx)
31 if err != nil { 31 if err != nil {
32 - return errorConnection{err}, err 32 + return errorConn{err}, err
33 } 33 }
34 - return &pooledConnection{p: p, c: c}, nil 34 + return &activeConn{p: p, pc: pc}, nil
35 } 35 }
@@ -36,18 +36,9 @@ type Message struct { @@ -36,18 +36,9 @@ type Message struct {
36 // The originating channel. 36 // The originating channel.
37 Channel string 37 Channel string
38 38
39 - // The message data.  
40 - Data []byte  
41 -}  
42 -  
43 -// PMessage represents a pmessage notification.  
44 -type PMessage struct {  
45 - // The matched pattern. 39 + // The matched pattern, if any
46 Pattern string 40 Pattern string
47 41
48 - // The originating channel.  
49 - Channel string  
50 -  
51 // The message data. 42 // The message data.
52 Data []byte 43 Data []byte
53 } 44 }
@@ -102,9 +93,9 @@ func (c PubSubConn) Ping(data string) error { @@ -102,9 +93,9 @@ func (c PubSubConn) Ping(data string) error {
102 return c.Conn.Flush() 93 return c.Conn.Flush()
103 } 94 }
104 95
105 -// Receive returns a pushed message as a Subscription, Message, PMessage, Pong  
106 -// or error. The return value is intended to be used directly in a type switch  
107 -// as illustrated in the PubSubConn example. 96 +// Receive returns a pushed message as a Subscription, Message, Pong or error.
  97 +// The return value is intended to be used directly in a type switch as
  98 +// illustrated in the PubSubConn example.
108 func (c PubSubConn) Receive() interface{} { 99 func (c PubSubConn) Receive() interface{} {
109 return c.receiveInternal(c.Conn.Receive()) 100 return c.receiveInternal(c.Conn.Receive())
110 } 101 }
@@ -135,11 +126,11 @@ func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interfac @@ -135,11 +126,11 @@ func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interfac
135 } 126 }
136 return m 127 return m
137 case "pmessage": 128 case "pmessage":
138 - var pm PMessage  
139 - if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil { 129 + var m Message
  130 + if _, err := Scan(reply, &m.Pattern, &m.Channel, &m.Data); err != nil {
140 return err 131 return err
141 } 132 }
142 - return pm 133 + return m
143 case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": 134 case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
144 s := Subscription{Kind: kind} 135 s := Subscription{Kind: kind}
145 if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { 136 if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
@@ -17,9 +17,6 @@ github.com/davecgh/go-spew/spew @@ -17,9 +17,6 @@ github.com/davecgh/go-spew/spew
17 github.com/dgrijalva/jwt-go 17 github.com/dgrijalva/jwt-go
18 # github.com/fsnotify/fsnotify v1.4.7 18 # github.com/fsnotify/fsnotify v1.4.7
19 github.com/fsnotify/fsnotify 19 github.com/fsnotify/fsnotify
20 -# github.com/garyburd/redigo v1.6.0  
21 -github.com/garyburd/redigo/internal  
22 -github.com/garyburd/redigo/redis  
23 # github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 20 # github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
24 github.com/gin-contrib/sse 21 github.com/gin-contrib/sse
25 # github.com/gin-gonic/gin v1.4.0 22 # github.com/gin-gonic/gin v1.4.0
@@ -29,6 +26,8 @@ github.com/gin-gonic/gin/internal/json @@ -29,6 +26,8 @@ github.com/gin-gonic/gin/internal/json
29 github.com/gin-gonic/gin/render 26 github.com/gin-gonic/gin/render
30 # github.com/golang/protobuf v1.3.1 27 # github.com/golang/protobuf v1.3.1
31 github.com/golang/protobuf/proto 28 github.com/golang/protobuf/proto
  29 +# github.com/gomodule/redigo v1.7.0
  30 +github.com/gomodule/redigo/redis
32 # github.com/google/go-cmp v0.2.0 31 # github.com/google/go-cmp v0.2.0
33 github.com/google/go-cmp/cmp 32 github.com/google/go-cmp/cmp
34 github.com/google/go-cmp/cmp/internal/diff 33 github.com/google/go-cmp/cmp/internal/diff