gore: github.com/keimoon/gore Index | Files

package gore

import "github.com/keimoon/gore"

Package gore is a full feature Redis client for Go:

- Convenient command building and reply parsing
- Pipeline, multi-exec, LUA scripting
- Pubsub
- Connection pool
- Redis sentinel
- Client implementation of sharding

Connections

Gore only supports TCP connection for Redis. The connection is thread-safe and can be auto-repaired with or without sentinel.

conn, err := gore.Dial("localhost:6379") //Connect to redis server at localhost:6379
if err != nil {
  return
}
defer conn.Close()

Command

Redis command is built with NewCommand

gore.NewCommand("SET", "kirisame", "marisa") // SET kirisame marisa
gore.NewCommand("ZADD", "magician", 1337, "alice") // ZADD magician 1337 alice
gore.NewCommand("HSET", "sdm", "sakuya", 99) // HSET smd sakuya 99

In the last command, the value stored by redis will be the string "99", not the integer 99.

Integer and float values are converted to string using strconv
Boolean values are convert to "1" and "0"
Nil values are stored as zero length string
Other types are converted to string using standard fmt.Sprint

To efficiently store integer, you can use gore.FixInt or gore.VarInt

Compact integer

Gore supports compacting integer to reduce memory used by redis. There are 2 ways of compacting integer:

gore.FixInt stores an integer as a fixed 8 bytes []byte.
gore.VarInt encodes an integer with variable length []byte.

gore.NewCommand("SET", "fixint", gore.FixInt(1337)) // Set fixint as an 8 bytes []byte
gore.NewCommand("SET", "varint", gore.VarInt(1337)) // varint only takes 3 bytes

Reply

A redis reply is return when the command is run on a connection

rep, err := gore.NewCommand("GET", "kirisame").Run(conn)

Parsing the reply is straightforward:

s, _ := rep.String()  // Return string value if reply is simple string (status) or bulk string
b, _ := rep.Bytes()   // Return a byte array
x, _ := rep.Integer() // Return integer value if reply type is integer (INCR, DEL)
e, _ := rep.Error()   // Return error message if reply type is error
a, _ := rep.Array()   // Return reply list if reply type is array (MGET, ZRANGE)

Reply converting

Reply support convenient methods to convert to other types

x, _ := rep.Int()    // Convert string value to int64. This method is different from rep.Integer()
f, _ := rep.Float()  // Convert string value to float64
t, _ := rep.Bool()   // Convert string value to boolean, where "1" is true and "0" is false
x, _ := rep.FixInt() // Convert string value to FixInt
x, _ := rep.VarInt() // Convert string value to VarInt

To convert an array reply to a slice, you can use Slice method:

s := []int
err := rep.Slice(&s) // Convert an array reply to a slice of integer

The following slice element types are supported:

- integer (int, int64)
- float (float64)
- string and []byte
- FixInt and VarInt
- *gore.Pair for converting map data from HGETALL or ZRANGE WITHSCORES

Reply returns from HGETALL or SENTINEL master can be converted into a map using Map:

m, err:= rep.Map()

Pipeline

Gore supports pipelining using gore.Pipeline:

p := gore.NewPipeline()
p.Add(gore.NewCommand("SET", "kirisame", "marisa"))
p.Add(gore.NewCommand("SET", "alice", "margatroid"))
replies, _ := p.Run(conn)
for _, r := range replies {
    // Deal with individual reply here
}

Script

Script can be set from a string or read from a file, and can be executed over a connection. Gore makes sure to use EVALSHA before using EVAL to save bandwidth.

s := gore.NewScript()
s.SetBody("return redis.call('SET', KEYS[1], ARGV[1])")
rep, err := s.Execute(conn, 1, "kirisame", "marisa")

Script can be loaded from a file:

s := gore.NewScript()
s.ReadFromFile("scripts/set.lua")
rep, err := s.Execute(conn, 1, "kirisame", "marisa")

Script map

If your application use a lot of script files, you can manage them through ScriptMap

gore.LoadScripts("scripts", ".*\\.lua") // Load all .lua file from scripts folder
s := gore.GetScripts("set.lua") // Get script from set.lua file
rep, err := s.Execute(conn, 1, "kirisame", "marisa") // And execute

Pubsub

Publish message to a channel is easy, you can use gore.Command to issue a PUBLISH over a connection, or use gore.Publish method:

gore.Publish(conn, "touhou", "Hello!")

To handle subscriptions, you should allocate a dedicated connection and assign it to gore.Subscriptions:

subs := gore.NewSubscriptions(conn)
subs.Subscribe("test")
subs.PSubscribe("tou*")

To receive messages, the subcriber should spawn a new goroutine and use Subscriptions Message channel:

go func() {
    for message := range subs.Message() {
        if message == nil {
             break
        }
        fmt.Println("Got message from %s, originate from %s: %s", message.Channel, message.OriginalChannel, message.Message)
    }
}()

Connection pool

To use connection pool, a Pool should be created when application startup. The Dial() method of the pool should be called to make initial connection to the redis server. If Dial() fail, it is up to the application to decide to fail fast, or wait and connect again later.

pool := &gore.Pool{
    InitialConn: 5,  // Initial number of connections to open
    MaximumConn: 10, // Maximum number of connections to open
}
err := pool.Dial("localhost:6379")
if err != nil {
    log.Error(err)
    return
}
...

In each goroutine, a connection from the pool can be get by Acquire() method. Release() method should always be called later to return the connection to the pool, even in error situation.

// Inside a goroutine
conn, err := pool.Acquire()
if err != nil {
    // Error can happens when goroutine try to acquire a conn
    // from the pool. Application should fail fast here.
    return
}
defer pool.Release(conn)
if conn == nil {
    // This happens when the pool was closed. Application should
    // fail here.
    return
}
// Do every thing with the conn, exclusively.
...

To gracefully close the pool, call Close() method anywhere in your program.

Transaction

Transaction is implemented using MULTI, EXEC and WATCH. Using transaction directly with a Conn is not goroutine-safe, so transaction should be used with connection pool only.

tr := gore.NewTransaction(conn)
tr.Watch("a key") // Watch a key
tr.Watch("another key")
rep, _ := NewCommand("GET", "a key").Run(conn)
value, _ := rep.Int()
tr.Add(NewCommand("SET", "a key", value + 1)) // Add a command to the transaction
_, err := tr.Commit() // Commit the transaction
if err == nil {
     // Transaction OK!!!
} else if err == gore.ErrKeyChanged {
     // Watched key has been changed, transaction should be started over.
} else {
     // Other errors, transaction should be aborted
}

Authentication

Gore supports Redis authentication in single connection, pool, sentinel.

Authentication with a single connection can be done by sending "AUTH" command to redis server as normal, but this can be trouble some when the server is down, and is reconnected after that. To deal with this problem, gore provides conn.Auth() method:

conn.Auth("secret password")

This method should be called when the connection is initialized. By calling Auth(), when gore tries to reconnect, is will also attempt to send AUTH command to redis server right after the connection is made.

To configure Auth password with gore.Pool, you can set pool.Password before calling pool.Dial(). Like gore.Conn, gore.Pool also automatically send AUTH command when reconnected.

If you are using sentinel to retrieve Pool or Cluster, instead of using GetPool or GetCluster method, you can use GetPoolWithPassword or GetClusterWithPassword to connect with a password-protected pool/cluster

Sentinel

Redis Sentinel is a system that monitors other Redis instance, notify application when something is wrong with monitored Redis instance, and do automatic failover. Please note that Redis Sentinel is still in beta stage, and only supported fully in Redis version 2.8 and above. For more information about setting up Redis Sentinel, please refer to the official document at http://redis.io/topics/sentinel

Using Redis Sentinel with gore is simple:

// First, you need to create a Sentinel object:
s := gore.NewSentinel()
// Add some Sentinel servers to this object.
// In production environment, you should have at least 3 Sentinel Servers
s.AddServer("127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381")
// Initialize the Sentinel
err := s.Dial()
if err != nil {
    return
}
// Now, the Sentinel is ready, you can get a monitored pool of connection from the
// sentinel by using one function:
pool, err := s.GetPool("mymaster")

The name of the pool ("mymaster") must be an already monitored instance name, otherwise, the function will return ErrNil. The application also should not call GetPool function repeatedly because internal locking may cause dropping in performance. It should assign and reuse the pool variable instead. Because the GetPool function is normally used when the application starts up, it will fail immediately if the redis instance is still down. Application can use a for loop and sleep to retry to connect.

Sharding

Gore supports simple sharding strategy: a fixed number of Redis instances are grouped into "cluster", each instance holds a portion of the cluster keyset.

When a single command needed to be execute on the cluster, gore will redirect the command to approriate instance based on the key. Gore makes sure that each key will be redirected to only one instance consistently. Because of the nature of the fixed-sharding, the number of Redis instances in the cluster should never change, and pipeline or transaction is not supported.

Gore provides two ways to connect to a cluster.

The first way is using Sentinel. All Redis instances in the same cluster should have the same prefix, and the suffix should be a number. For example: "mycluster1", "mycluster2", ..., "mycluster20". Using Sentinel, you can get a cluster relatively easy:

s := NewSentinel()
s.AddServer("127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381")
err := s.Dial()
if err != nil {
    return
}
c, err := s.GetCluster("mycluster")

The second way is to add shard to a cluster manually:

c := NewCluster()
c.AddShard("127.0.0.1:6379", "127.0.0.1:6380")
err := c.Dial()
if err != nil {
    return
}

Using cluster

A single command can be ran on the cluster with Execute:

rep, err := c.Execute(NewCommand("SET", "kirisame", "marisa"))
if err != nil || !rep.IsOk() {
    return
}
rep, err := c.Execute(NewCommand("GET", "kirisame"))
if err != nil {
    return
}
value, _ := rep.String() // value should be "marisa"

Index

Package Files

command.go config.go conn.go doc.go error.go number.go pipeline.go pool.go pubsub.go reply.go script.go sentinel.go sharding.go transaction.go

Constants

const (
    ReplyString  = 1
    ReplyArray   = 2
    ReplyInteger = 3
    ReplyNil     = 4
    ReplyStatus  = 5
    ReplyError   = 6
)

Reply type, similar to Hiredis

Variables

var (
    // ErrNotConnected is returned when attempt to send command when connection is down
    ErrNotConnected = errors.New("not connected")
    // ErrEmptyScript is returned when try to execute an empty script
    ErrEmptyScript = errors.New("empty script")
    // ErrType is returned when convert between different reply types
    ErrType = errors.New("type error")
    // ErrConvert is returned when convert between data types
    ErrConvert = errors.New("convert error")
    // ErrKeyChanged is returned when transaction fails because watched keys have been changed
    ErrKeyChanged = errors.New("key changed")
    // ErrTransactionAborted is returned when tracsaction fails because of other reasons
    ErrTransactionAborted = errors.New("transaction aborted")
    // ErrNil is for nil reply
    ErrNil = errors.New("nil value")
    // ErrAuth is returned when redis AUTH fail
    ErrAuth = errors.New("authentication fail")
    //ErrNoShard is returned when trying to connect with a cluster with no shard
    ErrNoShard = errors.New("no shard")
    // ErrNoKey is returned when sending command with no key to the cluster
    ErrNoKey = errors.New("no key")
    // ErrWrite is returned when connection cannot be written
    ErrWrite = errors.New("write error")
    // ErrRead is returned when connection cannot be read
    ErrRead = errors.New("read error")
)
var Config = &struct {
    ConnectTimeout  int
    RequestTimeout  int
    ReconnectTime   int
    PoolInitialSize int
    PoolMaximumSize int
}{
    ConnectTimeout:  5,
    RequestTimeout:  10,
    ReconnectTime:   2,
    PoolInitialSize: 5,
    PoolMaximumSize: 10,
}

Config keeps some default configurations. Time is measured in second

var (
    // ErrNumberFormat is returned when formatting number fails.
    ErrNumberFormat = errors.New("number format error")
)

func AddScript Uses

func AddScript(scriptName string, script *Script)

AddScript a script to the default script map

func DefaultShardStrategy Uses

func DefaultShardStrategy(key string, size int) int

DefaultShardStrategy converts a string key into number and takes modulo with the size of cluster

func DeleteScript Uses

func DeleteScript(scriptName string)

DeleteScript a script from the default script map

func LoadScripts Uses

func LoadScripts(folder, pattern string) error

LoadScripts loads all script files from a folder with a regular expression pattern to the default script map. Loaded script will be keyed by its file name. This method can be called many times to reload script files.

func Publish Uses

func Publish(conn *Conn, channel string, message interface{}) error

Publish a message to a channel over conn

func ToFixInt Uses

func ToFixInt(b []byte) (int64, error)

ToFixInt converts a fixed size byte array to a int64

func ToVarInt Uses

func ToVarInt(b []byte) (int64, error)

ToVarInt converts a base-128 byte array to a int64

type Cluster Uses

type Cluster struct {
    ShardStrategy func(string, int) int
    // contains filtered or unexported fields
}

Cluster consists of fix number of shards, with each shard holds a portion of the keyset. Cluster can be created by adding shards, or using sentinel.

func NewCluster Uses

func NewCluster() *Cluster

NewCluster creates new cluster. You must add shards to this cluster manually

func (*Cluster) AddShard Uses

func (c *Cluster) AddShard(addresses ...string)

AddShard add a list of shards to the cluster.

func (*Cluster) AddShardWithPassword Uses

func (c *Cluster) AddShardWithPassword(address, password string)

AddShardWithPassword add a password-protected shard

func (*Cluster) Dial Uses

func (c *Cluster) Dial() (err error)

Dial connects the cluster to all shards. If one shard cannot be connected, the whole operation will fail.

func (*Cluster) Execute Uses

func (c *Cluster) Execute(cmd *Command) (*Reply, error)

Execute runs a command on the cluster. The command will be send to appropriate shard based on its key. If the command has no key (PING, INFO), this function returns ErrNoKey

type Command Uses

type Command struct {
    // contains filtered or unexported fields
}

Command sent to redis

func NewCommand Uses

func NewCommand(name string, args ...interface{}) *Command

NewCommand returns a new Command

func (*Command) Run Uses

func (cmd *Command) Run(conn *Conn) (r *Reply, err error)

Run sends command to redis

func (*Command) Send Uses

func (cmd *Command) Send(conn *Conn) (err error)

Send safely sends a command over conn

type Conn Uses

type Conn struct {
    RequestTimeout time.Duration
    // contains filtered or unexported fields
}

Conn holds a persistent connection to a redis server

func Dial Uses

func Dial(address string) (*Conn, error)

Dial opens a TCP connection with a redis server.

func DialTimeout Uses

func DialTimeout(address string, timeout time.Duration) (*Conn, error)

DialTimeout opens a TCP connection with a redis server with a connection timeout

func (*Conn) Auth Uses

func (c *Conn) Auth(password string) error

Auth makes authentication with redis server

func (*Conn) Close Uses

func (c *Conn) Close() error

Close closes the connection

func (*Conn) GetAddress Uses

func (c *Conn) GetAddress() string

GetAddress returns connection address

func (*Conn) IsConnected Uses

func (c *Conn) IsConnected() bool

IsConnected returns true if connection is okay

func (*Conn) Lock Uses

func (c *Conn) Lock()

Lock locks the whole connection

func (*Conn) Unlock Uses

func (c *Conn) Unlock()

Unlock unlocks the whole connection

type FixInt Uses

type FixInt int64

FixInt represents a fixed size int64 number

func (FixInt) Bytes Uses

func (x FixInt) Bytes() []byte

Bytes converts a FixInt to a byte array

type Message Uses

type Message struct {
    // message or pmessage
    Type string
    // The channel/pchannel the client subscribed to. For example: "test", "te*"
    Channel string
    // The channel that publisher published to. For example "test", "text"
    OriginalChannel string
    // The payload
    Message []byte
}

Message is a nofitication from a subscribed channel or pchannel

type Pair Uses

type Pair struct {
    First  []byte
    Second []byte
}

Pair holds a pair of value, such as reply from HGETALL or ZRANGE [WITHSCORES]

type Pipeline Uses

type Pipeline struct {
    // contains filtered or unexported fields
}

Pipeline keeps a list of command for sending to redis once, saving network roundtrip

func NewPipeline Uses

func NewPipeline() *Pipeline

NewPipeline returns new Pipeline

func (*Pipeline) Add Uses

func (p *Pipeline) Add(cmd ...*Command)

Add appends new commands to the pipeline

func (*Pipeline) Reset Uses

func (p *Pipeline) Reset()

Reset clears all command in the pipeline

func (*Pipeline) Run Uses

func (p *Pipeline) Run(conn *Conn) (r []*Reply, err error)

Run sends the pipeline and returns a slice of Reply

type Pool Uses

type Pool struct {
    // Request timeout for each connection
    RequestTimeout time.Duration
    // Initial number of connection to open
    InitialConn int
    // Maximum number of connection to open
    MaximumConn int
    // Password to send after connection is opened
    Password string
    // contains filtered or unexported fields
}

Pool is a pool of connection. The application acquires connection from pool using Acquire() method, and when done, returns it to the pool with Release().

func (*Pool) Acquire Uses

func (p *Pool) Acquire() (*Conn, error)

Acquire returns a usable, exclusive connection for the goroutine. If this function return a nil connection, application can check the error to know whether there is really an error or it is because the pool was closed. If the pool was closed, the returned error will also be nil.

func (*Pool) Close Uses

func (p *Pool) Close()

Close properly closes the pool

func (*Pool) Dial Uses

func (p *Pool) Dial(address string) error

Dial initializes connection from the pool to redis server. If the redis server cannot be connected, this function returns an error, and the application should fail accordingly.

func (*Pool) GetAddress Uses

func (p *Pool) GetAddress() string

GetAddress returns pool address

func (*Pool) IsConnected Uses

func (p *Pool) IsConnected() bool

IsConnected returns pool connection status. This function only works when sentinel is enabled. When sentinel is disabled, false positive may occur.

func (*Pool) Release Uses

func (p *Pool) Release(conn *Conn)

Release pushs the connection back to the pool. The pool makes sure this connection must be usable before pushing it back to the acquirable list.

type Reply Uses

type Reply struct {
    // contains filtered or unexported fields
}

Reply holds redis reply

func Receive Uses

func Receive(conn *Conn) (r *Reply, err error)

Receive safely read a reply from conn

func (*Reply) Array Uses

func (r *Reply) Array() ([]*Reply, error)

Array returns array value of a reply

func (*Reply) Bool Uses

func (r *Reply) Bool() (bool, error)

Bool parses string value to boolean. Integer 0 and string "0" returns false while integer 1 and string "1" returns true. Other values will cause ErrConvert

func (*Reply) Bytes Uses

func (r *Reply) Bytes() ([]byte, error)

Bytes returns string value of a reply as byte array

func (*Reply) Error Uses

func (r *Reply) Error() (string, error)

Error returns error message

func (*Reply) FixInt Uses

func (r *Reply) FixInt() (int64, error)

FixInt returns a fixed size int64

func (*Reply) Float Uses

func (r *Reply) Float() (float64, error)

Float parses string value to float64

func (*Reply) Int Uses

func (r *Reply) Int() (int64, error)

Int returns integer value (for example from INCR) or convert string value to integer if possible

func (*Reply) Integer Uses

func (r *Reply) Integer() (int64, error)

Integer returns integer value (for example from INCR) or convert string value to integer if possible

func (*Reply) IsArray Uses

func (r *Reply) IsArray() bool

IsArray checks if reply is an array reply or not

func (*Reply) IsError Uses

func (r *Reply) IsError() bool

IsError checks if reply is an error reply or not

func (*Reply) IsInteger Uses

func (r *Reply) IsInteger() bool

IsInteger checks if reply is a integer reply or not

func (*Reply) IsNil Uses

func (r *Reply) IsNil() bool

IsNil checks if reply is nil or not

func (*Reply) IsOk Uses

func (r *Reply) IsOk() bool

IsOk checks if reply is a status reply with "OK" response

func (*Reply) IsStatus Uses

func (r *Reply) IsStatus() bool

IsStatus checks if reply is a status or not

func (*Reply) IsString Uses

func (r *Reply) IsString() bool

IsString checks if reply is a string reply or not

func (*Reply) Map Uses

func (r *Reply) Map() (map[string]string, error)

Map converts the reply into a map[string]string. It will return error unless the reply is an array reply from HGETALL, or SENTINEL master

func (*Reply) Slice Uses

func (r *Reply) Slice(s interface{}) error

Slice parses the reply to a slice. The element of the destination slice must be integer, float, boolean, string, []byte, FixInt, VarInt, or a Pair

func (*Reply) String Uses

func (r *Reply) String() (string, error)

String returns string value of a reply

func (*Reply) Type Uses

func (r *Reply) Type() int

Type returns reply type

func (*Reply) VarInt Uses

func (r *Reply) VarInt() (int64, error)

VarInt returns a base-128 encoded int64

type Script Uses

type Script struct {
    // contains filtered or unexported fields
}

Script represents a Lua script.

func GetScript Uses

func GetScript(scriptName string) *Script

GetScript a script by its name from defaultScriptMap . Nil value will be returned if the name is not found

func NewScript Uses

func NewScript() *Script

NewScript returns a new Lua script

func (*Script) Execute Uses

func (s *Script) Execute(conn *Conn, keyCount int, keysAndArgs ...interface{}) (*Reply, error)

Execute runs the script over a connection

func (*Script) ReadFromFile Uses

func (s *Script) ReadFromFile(file string) error

ReadFromFile reads the script from a file

func (*Script) SetBody Uses

func (s *Script) SetBody(body string) error

SetBody sets script body and its SHA value

type ScriptMap Uses

type ScriptMap struct {
    // contains filtered or unexported fields
}

ScriptMap is a thread-safe map from script name to its content

func NewScriptMap Uses

func NewScriptMap() *ScriptMap

NewScriptMap makes a new ScriptMap

func (*ScriptMap) Add Uses

func (sm *ScriptMap) Add(scriptName string, script *Script)

Add a script to the script map

func (*ScriptMap) Delete Uses

func (sm *ScriptMap) Delete(scriptName string)

Delete a script from the script map

func (*ScriptMap) Get Uses

func (sm *ScriptMap) Get(scriptName string) *Script

Get a script by its name. Nil value will be returned if the name is not found

func (*ScriptMap) Load Uses

func (sm *ScriptMap) Load(folder, pattern string) error

Load loads all script files from a folder with a regular expression pattern. Loaded script will be keyed by its file name. This method can be called many times to reload script files.

type Sentinel Uses

type Sentinel struct {
    // contains filtered or unexported fields
}

Sentinel is a special Redis process that monitors other Redis instances, does fail-over, notifies client status of all monitored instances.

func NewSentinel Uses

func NewSentinel() *Sentinel

NewSentinel returns new Sentinel

func (*Sentinel) AddServer Uses

func (s *Sentinel) AddServer(addresses ...string)

AddServer adds new sentinel servers. Only one sentinel server is active at any time. If this server fails, gore will connect to other sentinel servers immediately.

AddServer can be called at anytime, to add new server on the fly. In production environment, you should always have at least 3 sentinel servers up and running.

func (*Sentinel) Close Uses

func (s *Sentinel) Close()

Close gracefully closes the sentinel and all monitored connections

func (*Sentinel) Dial Uses

func (s *Sentinel) Dial() (err error)

Dial connects to one sentinel server in the list. If it fails to connect, it moves to the next on the list. If all servers cannot be connected, Init return error.

func (*Sentinel) GetCluster Uses

func (s *Sentinel) GetCluster(name string) (c *Cluster, err error)

GetCluster returns a cluster monitored by the sentinel. The name of the cluster will determine name of Redis instances. For example, if the cluster name is "mycluster", the instances' name maybe "mycluster1", "mycluster2", ...

func (*Sentinel) GetClusterWithPassword Uses

func (s *Sentinel) GetClusterWithPassword(name string, password string) (c *Cluster, err error)

GetClusterWithPassword returns a password-protected cluster monitored by the sentinel.

func (*Sentinel) GetPool Uses

func (s *Sentinel) GetPool(name string) (*Pool, error)

GetPool returns a pool of connection from a pool name. If the pool has not been retrieved before, gore will attempt to fetch the address from the sentinel server, and initialize connections with this address. The application should never call this function repeatedly to get the same pool, because internal locking can cause performance to drop. An error can be returned if the pool name is not monitored by the sentinel, or the redis server is currently dead, or the redis server cannot be connected (for example: firewall issues).

func (*Sentinel) GetPoolWithPassword Uses

func (s *Sentinel) GetPoolWithPassword(name string, password string) (*Pool, error)

GetPoolWithPassword returns a pool of connection to a password-protected instance

type Subscriptions Uses

type Subscriptions struct {
    // contains filtered or unexported fields
}

Subscriptions keeps all SUBSCRIBE and PSUBSCRIBE channels, and handles all errors and re-subcription process when the connection is down then reconnected. A dedicated connection should be used for Subscriptions

func NewSubscriptions Uses

func NewSubscriptions(conn *Conn) *Subscriptions

NewSubscriptions returns new Subscriptions

func (*Subscriptions) Close Uses

func (s *Subscriptions) Close()

Close terminates the subscriptions. The connection is NOT closed. You should close it if you do not want to use anymore.

func (*Subscriptions) IsClosed Uses

func (s *Subscriptions) IsClosed() bool

IsClosed returns true if the subscription is no longer available

func (*Subscriptions) Message Uses

func (s *Subscriptions) Message() chan *Message

Message returns a channel for receiving message event. A nil message indicates the channel is closed. The channel should be used from a separated goroutine. For example:

for message := range subs.Message() {
   if message == nil {
       break
   }
   ...
}

func (*Subscriptions) PSubscribe Uses

func (s *Subscriptions) PSubscribe(channel ...string) error

PSubscribe subscribes to a list of channels with given pattern

func (*Subscriptions) PUnsubscribe Uses

func (s *Subscriptions) PUnsubscribe(channel ...string) error

PUnsubscribe unsubscribes to a list of channels with given pattern

func (*Subscriptions) Subscribe Uses

func (s *Subscriptions) Subscribe(channel ...string) error

Subscribe subscribes to a list of channels

func (*Subscriptions) Unsubscribe Uses

func (s *Subscriptions) Unsubscribe(channel ...string) error

Unsubscribe unsubscribes to a list of channels

type Transaction Uses

type Transaction struct {
    // contains filtered or unexported fields
}

Transaction implements MULTI/EXEC/WATCH protocol of redis. Transaction must be used with connection pool, or undefined behavior. may orcur when used from multiple goroutine.

func NewTransaction Uses

func NewTransaction(conn *Conn) *Transaction

NewTransaction returns new transaction

func (*Transaction) Add Uses

func (t *Transaction) Add(cmd ...*Command)

Add appends commands to the transaction

func (*Transaction) Commit Uses

func (t *Transaction) Commit() ([]*Reply, error)

Commit commits the whole transaction. If transaction fail, ErrTransactionAborted is returned. If watched key has been modified, ErrKeyChanged is returned.

func (*Transaction) Discard Uses

func (t *Transaction) Discard() error

Discard discards the transaction

func (*Transaction) Watch Uses

func (t *Transaction) Watch(key ...string) error

Watch watches some keys. If the key has been changed before Exec, the transaction will be aborted

type VarInt Uses

type VarInt int64

VarInt represents a base-128 int64 number

func (VarInt) Bytes Uses

func (x VarInt) Bytes() []byte

Bytes converts a VarInt to a byte array

Package gore imports 15 packages (graph) and is imported by 26 packages. Updated 2016-07-20. Refresh now. Tools for package owners.