Coder Social home page Coder Social logo

goredis's Introduction

goredis

GoDoc

redis client in golang

Go or Golang is an open source programming language that makes it easy to build simple, reliable, and efficient software.

Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.

  • Pure golang, and doesn't depend on any 3rd party libraries;
  • Hight test coverage and will continue to improve;
  • Tested under Go 1.2 and Redis 2.8.3;
  • Tested under Go 1.2.1 and Redis 2.8.4;

Features

Document

Simple Example

Connect:

client, err := Dial()
client, err := Dial(&DialConfig{Address: "127.0.0.1:6379"})
client, err := DialURL("tcp://auth:[email protected]:6379/0?timeout=10s&maxidle=1")

Try a redis command is simple too, let's do GET/SET:

err := client.Set("key", "value", 0, 0, false, false)
value, err := client.Get("key")

Or you can execute a custom command with Redis.ExecuteCommand method:

reply, err := client.ExecuteCommand("SET", "key", "value")
err := reply.OKValue()

And then a Reply struct which represent the redis response data is defined:

type Reply struct {
	Type    int
	Error   string
	Status  string
	Integer int64  // Support Redis 64bit integer
	Bulk    []byte // Support Redis Null Bulk Reply
	Multi   []*Reply
}

Reply.Type is defined as:

const (
	ErrorReply = iota
	StatusReply
	IntegerReply
	BulkReply
	MultiReply
)

Reply struct has many useful methods:

func (rp *Reply) IntegerValue() (int64, error)
func (rp *Reply) BoolValue() (bool, error)
func (rp *Reply) StatusValue() (string, error)
func (rp *Reply) OKValue() error
func (rp *Reply) BytesValue() ([]byte, error)
func (rp *Reply) StringValue() (string, error)
func (rp *Reply) MultiValue() ([]*Reply, error)
func (rp *Reply) HashValue() (map[string]string, error)
func (rp *Reply) ListValue() ([]string, error)
func (rp *Reply) BytesArrayValue() ([][]byte, error)
func (rp *Reply) BoolArrayValue() ([]bool, error)

You can find more examples in test files.

Run Test

normal test:

go test

coverage test:

go test -cover

coverage test with html result:

go test -coverprofile=cover.out
go tool cover -html=cover.out

Welcome to report issues :)

Run Benchmark

go test -test.run=none -test.bench="Benchmark.*"

At my virtualbox Ubuntu 13.04 with single CPU: Intel(R) Core(TM) i5-3450 CPU @ 3.10GHz, get result:

BenchmarkPing	   50000	     40100 ns/op
BenchmarkLPush	   50000	     34939 ns/op
BenchmarkLRange	   50000	     41420 ns/op
BenchmarkGet	   50000	     37948 ns/op
BenchmarkIncr	   50000	     44460 ns/op
BenchmarkSet	   50000	     41300 ns/op

Welcome to show your benchmark result :)

License

The MIT License (MIT) Copyright (c) 2013 xuyu

goredis's People

Contributors

3onyc avatar andreib1 avatar iwanbk avatar skastel avatar xuyu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

goredis's Issues

Feature request/discussion

Introduction

First, I dig the way you've organized the code on commands.

I'm looking at adding support for the info and sentinel commands, and based on some attempts implementing them using other libraries I have some ideas around them. Before I start working on adding these commands here I want to get some discussion around what I think they should look like to make sure I'm not entirely out of the field here.

Command: Info

Info takes, optionally, a section name and returns the info for that section, if "all" is given it returns all of it.

The string format it returns is:

#sectionname
key:value
key:value

For every section requested this sequence is repeated.

Unfortunately this means the user has to parse it. As the first item in your feature list is "Python Redis Client Like API", I'd like to see this command implemented to return a struct (or map?) or array of structs/maps (in the case of "all") rather than simply returning a string. For comparison, redis-py returns a dictionary/nested-dictionaries.

I am thinking if we defined a struct for each section we could parse the results into the appropriate struct and return either the struct or a list of structs; or would it be better to nest the sub-sections as structs in a larger Info struct?

In my somewhat-of-a-hack-feeling code (in other libs) I've split up the reply string to provide a map[string]string and used the mapstructure library to turn that into a struct. I'm new to Go and that looked the easiest way for a newcomer. Unfortunately that would introduce a dependency so I suspect it would need to be done more natively. If someone has pointers to a solid way to do that w/o a third party library, please let me know.

A related command I'd like to see implemented is the sentinel command.

Command: Sentinel

The sentinel command is a means for interrogating a redis sentinel for what to connect to in a sentinel managed redis pod (master+slaves). It is primarily based on a small set of subcommands.

SENTINEL MASTER <name>
This command will return a key/value sequence (like you'd get with an hgetall) with information on the pod specified.

SENTINEL MASTERS
This returns a list of 'sentinel master' results - an entry for each pod managed by the sentinel.

SENTINEL SLAVE <name>

Same reply type as masters, but returns information for each slave in the pod.

I'd like to see these come back as structs. Something along the lines of a MasterData struct, a SlaveData struct, and possibly a PodStruct which would contain the previous structs to portray the configuration of the entire pod.

With these commands supported you'd actually have part of what is needed to implement sentinel support at the connection level. At a minimum it would allow the calling code to implement support for Redis Sentinel.

it is now occurring to me this might be best as two issues. If desired I could break this into two github issues so they could be tracked independently.

I look forward to your thoughts on the idea(s)? I'm likely to implement them on my own regardless (as I need these capabilities), but would rather do them in away that would be considered for inclusion. :)

Cheers,
Bill

Errors are ignored!

This package completely ignores errors. Conditions such as OOM are completely ignored and your program will blissfully continue on as no error condition is triggered.

No errors when trying to get element by key on a closed pool

I've been checking this project for a while and right now I've tried to use it on some of our projects. One problem we had was an error a friend made deferring the client.ClosePool() function and instead of using "defer", they just called it right away.

We didn't notice that until some SET commands took so long to respond (+20 secs) with an http error. The problem, however, was there: if you close the pool right once you connected to it, there's nothing telling you that you're querying a closed pool and instead, the queries took long enough to complete.

PubSub Error

Hi, total Go noob. Trying to setup a bare minimal pubsub client. The following code:

package main

import . "github.com/xuyu/goredis"

func main() {
    sub, err := PubSub()
}

Produces this error:

missing argument to conversion to goredis.PubSub: goredis.PubSub()

Any help would be great. Thanks.

ConfigSet sets empty values and ignores parameters

the ExecuteCommand in ConfigSet ignores the parameter and value.
It should be along the lines of:
file: server.go
func (r *Redis) ConfigSet(parameter, value string) error {
-- rp, err := r.ExecuteCommand("CONFIG", "SET")
++ rp, err := r.ExecuteCommand("CONFIG", "SET", parameter, value)

func Set has too many options

The method for setting a key's value (Set(...)) has too many arguments and duplicates functionality of other Redis commands.

Currently it has mandatory arguments for whether the key must or must not exist, and various levels of timeouts.

To set a key if and only if it doesn't exist the SetNx Redis command is the proper command to use, not Set. To Set a key and simultaneously it's expiration setex and psetex are used for seconds and milliseconds respectively. Each of these commands are currently available in the library.

Thus, these options should be pulled from the Set func and it be used solely for the redis "SET foo bar" operation.

For adding a "set only if key already exists" operation, a separate command should be created, rather than overloading the Set method. This change would break existing Set calls as they are currently being called with a handful of extraneous args, but in the long run will keep the API consistent with Redis' commands and the way other client libraries handle the Set operation. Doing this early will prevent this from being a larger issue as use of the library increases.

transaction Discard/Exec should put the connection back

Since the connection has been reserved for this purpose only and the Exec documentation even states that it puts the connection back to normal.

Requiring Close feels pretty cumbersome to me.

Please deprecate use of Transaction.Close and make it a no-op after Exec/Discard.

Normal and expected flow for transactions would be:

    t, _ := redis.Transaction()
    _ = transaction.Watch("mykey")
    // work and queue up commands
    if someError {
        _ = t.Discard()
    } else {
        _ = t.Exec()
    }

Examples documentation

I think we can improve documentation of how to use the library by having full examples.

For example if we had a directory examples, and in there we had sentinel.go which was a go run-nable Go program which connected to a local Redis sentinel instance and ran the various commands we would have a demo/howto on using the library to connect to and manage a Sentinel instance. We could have examples for each command group such as one for sorted sets, hashes, etc..

As I am developing those for my Sentinel and InfoStruct additions I would be willing get it started and add more as I go along.

Thoughts?

Redis Cluster

Hi,

I just wonder if you plan to implement Redis Cluster in a foreseable future ?

Set method errors on NX condition mismatch

From the Redis documentation:

Simple string reply: OK if SET was executed correctly. Null reply: a Null Bulk Reply is returned if the SET operation was not performed because the user specified the NX or XX option but the condition was not met.
https://redis.io/commands/set

Within the code the Set method performs an OKValue check which expects to see a StatusReply only. Therefore setting NX to true causes the error invalid reply type, not status even though the command was executed successfully and should not cause an error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.