正在显示
26 个修改的文件
包含
230 行增加
和
136 行删除
common/jwt_tset.go
0 → 100644
@@ -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 | } |
@@ -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 | ) |
@@ -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 { |
@@ -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} | ||
394 | - | ||
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 | 397 | + ac.pc = nil |
398 | + | ||
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 |
-
请 注册 或 登录 后发表评论