1 // Copyright 2012 Gary Burd 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package redis 16 17 import ( 18 "errors" 19 "time" 20 ) 21 22 // Error represents an error returned in a command reply. 23 type Error string 24 25 func (err Error) Error() string { return string(err) } 26 27 // Conn represents a connection to a Redis server. 28 type Conn interface { 29 // Close closes the connection. 30 Close() error 31 32 // Err returns a non-nil value when the connection is not usable. 33 Err() error 34 35 // Do sends a command to the server and returns the received reply. 36 Do(commandName string, args ...interface{}) (reply interface{}, err error) 37 38 // Send writes the command to the client's output buffer. 39 Send(commandName string, args ...interface{}) error 40 41 // Flush flushes the output buffer to the Redis server. 42 Flush() error 43 44 // Receive receives a single reply from the Redis server 45 Receive() (reply interface{}, err error) 46 } 47 48 // Argument is the interface implemented by an object which wants to control how 49 // the object is converted to Redis bulk strings. 50 type Argument interface { 51 // RedisArg returns a value to be encoded as a bulk string per the 52 // conversions listed in the section 'Executing Commands'. 53 // Implementations should typically return a []byte or string. 54 RedisArg() interface{} 55 } 56 57 // Scanner is implemented by an object which wants to control its value is 58 // interpreted when read from Redis. 59 type Scanner interface { 60 // RedisScan assigns a value from a Redis value. The argument src is one of 61 // the reply types listed in the section `Executing Commands`. 62 // 63 // An error should be returned if the value cannot be stored without 64 // loss of information. 65 RedisScan(src interface{}) error 66 } 67 68 // ConnWithTimeout is an optional interface that allows the caller to override 69 // a connection's default read timeout. This interface is useful for executing 70 // the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the 71 // server. 72 // 73 // A connection's default read timeout is set with the DialReadTimeout dial 74 // option. Applications should rely on the default timeout for commands that do 75 // not block at the server. 76 // 77 // All of the Conn implementations in this package satisfy the ConnWithTimeout 78 // interface. 79 // 80 // Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify 81 // use of this interface. 82 type ConnWithTimeout interface { 83 Conn 84 85 // Do sends a command to the server and returns the received reply. 86 // The timeout overrides the read timeout set when dialing the 87 // connection. 88 DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) 89 90 // Receive receives a single reply from the Redis server. The timeout 91 // overrides the read timeout set when dialing the connection. 92 ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) 93 } 94 95 var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout") 96 97 // DoWithTimeout executes a Redis command with the specified read timeout. If 98 // the connection does not satisfy the ConnWithTimeout interface, then an error 99 // is returned. 100 func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) { 101 cwt, ok := c.(ConnWithTimeout) 102 if !ok { 103 return nil, errTimeoutNotSupported 104 } 105 return cwt.DoWithTimeout(timeout, cmd, args...) 106 } 107 108 // ReceiveWithTimeout receives a reply with the specified read timeout. If the 109 // connection does not satisfy the ConnWithTimeout interface, then an error is 110 // returned. 111 func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) { 112 cwt, ok := c.(ConnWithTimeout) 113 if !ok { 114 return nil, errTimeoutNotSupported 115 } 116 return cwt.ReceiveWithTimeout(timeout) 117 } 118