Skip to content
This repository has been archived by the owner on Mar 11, 2020. It is now read-only.

parser Sscanf and error typos #27

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d3e36da
Comment 'disconnect detection' in order to prevent premature disconne…
schumajs Oct 18, 2013
7935a74
Remove unused imports.
schumajs Oct 18, 2013
3320833
Add 'incr' and 'decr' methods.
schumajs Oct 20, 2013
d1efde2
Do some minor refactorings.
schumajs Oct 20, 2013
fed12c0
Add 'expire' method.
schumajs Oct 21, 2013
8a2e874
Add 'exists' method.
schumajs Oct 21, 2013
7e66daf
Add ordered set methods.
schumajs Oct 23, 2013
b348418
Add 'ordered_set.go' (forgotten in last commit).
schumajs Oct 23, 2013
0549980
Allow pipelining
dim Mar 3, 2014
c8aabfc
Make Code public in the StatusReply
Jul 16, 2014
b65ad7f
Fix off-by-one in lowercase check.
Sep 2, 2014
4571491
Merge pull request #1 from koblas/master
Aug 16, 2015
5149060
Merge pull request #2 from alicebob/master
Aug 16, 2015
8f18975
Merge pull request #3 from storyfeed/master
Aug 16, 2015
1561785
fixed for go 1.5
tsanyen Nov 9, 2015
6545cdd
tidy
tsanyen Nov 9, 2015
894a2bc
Merge pull request #1 from operetta/master
jharlap Apr 19, 2016
7b771e3
Merge pull request #2 from rtoma/master
jharlap Apr 19, 2016
6068ddc
Fix LRANGE with negative stop index
jharlap Apr 20, 2016
880564c
Add Server.Close() method
jharlap Apr 20, 2016
c7a147c
Process requests one at a time
jharlap Apr 20, 2016
e7aa232
Close server more safely
jharlap Apr 20, 2016
0afb481
Have defaultHandler's DEL function check for brstack keys. Also fix t…
May 11, 2016
6554c60
Merge pull request #3 from minosabaki/FIX-DEL
jharlap May 11, 2016
e3117f8
Replace ListenAndServe with Start
jharlap May 20, 2016
e06c830
Fix error typos and quoted string formats
tgrennan Apr 1, 2016
b726c70
Print all debug to a configurable writer
tgrennan Apr 5, 2016
aa33f76
optimize empty DEBUG with a closure
tgrennan Apr 5, 2016
1889e56
DefaultHandler.Hset: make hvalues if nil
tgrennan Apr 6, 2016
fbe0fee
add NewStatusReply
tgrennan Apr 7, 2016
eaefa8e
example: fix import path to platinasystems fork
tgrennan Jun 7, 2016
18bf735
example, example/simple: s/ListenAndServe/Start/
tgrennan Jun 7, 2016
5d7696c
README: -remove broken travis link
tgrennan Jun 7, 2016
340ca98
remove print of "New client" on subscribe
tgrennan Jun 7, 2016
d92dd30
don't overwrite addr of unix proto if non-empty
tgrennan Jun 7, 2016
4be445c
retry listen
tgrennan Jun 7, 2016
9486d6a
go-redis-server: OK to Quit
tgrennan May 31, 2017
2aae595
go-redis-server: expedite quit
tgrennan Jun 7, 2017
fcb8fa7
go.mod: Initial commit
kph Oct 30, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
[![Build Status](https://travis-ci.org/dotcloud/go-redis-server.png)](https://travis-ci.org/dotcloud/go-redis-server)

Redis server protocol library
=============================

Expand Down
5 changes: 2 additions & 3 deletions auto.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (srv *Server) handlerFn(autoHandler interface{}, f *reflect.Value, checkers
ret = result[0].Interface()
return srv.createReply(request, ret)
}
return &StatusReply{code: "OK"}, nil
return &StatusReply{Code: "OK"}, nil
}, nil
}

Expand Down Expand Up @@ -148,13 +148,12 @@ func (srv *Server) createReply(r *Request, val interface{}) (ReplyWriter, error)
case *MonitorReply:
c := make(chan string)
srv.MonitorChans = append(srv.MonitorChans, c)
println("len monitor: ", len(srv.MonitorChans))
fmt.Println(Stderr, "len monitor: ", len(srv.MonitorChans))
v.c = c
return v, nil
case *ChannelWriter:
return v, nil
case *MultiChannelWriter:
println("New client")
for _, mcw := range v.Chans {
mcw.clientChan = r.ClientChan
}
Expand Down
1 change: 1 addition & 0 deletions auto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func TestAutoHandler(t *testing.T) {
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
defer srv.Close()
expected := []struct {
request *Request
expected []string
Expand Down
36 changes: 23 additions & 13 deletions debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,36 @@ package redis

import (
"fmt"
"io"
"os"
"runtime"
"strings"
)

// Debug function, if the debug flag is set, then display. Do nothing otherwise
// If Docker is in damon mode, also send the debug info on the socket
// Convenience debug function, courtesy of http://github.com/dotcloud/docker
func Debugf(format string, a ...interface{}) {
var Stderr = io.Writer(os.Stderr)

// This closure is a no-op unless the DEBUG env is non empty.
var Debugf = func(format string, a ...interface{}) {}

func init() {
if os.Getenv("DEBUG") != "" {
Debugf = ActualDebugf
}

// Retrieve the stack infos
_, file, line, ok := runtime.Caller(1)
if !ok {
file = "<unknown>"
line = -1
} else {
file = file[strings.LastIndex(file, "/")+1:]
}
}

fmt.Fprintf(os.Stderr, fmt.Sprintf("[%d] [debug] %s:%d %s\n", os.Getpid(), file, line, format), a...)
// If Docker is in damon mode, also send the debug info on the socket
// Convenience debug function, courtesy of http://github.com/dotcloud/docker
func ActualDebugf(format string, a ...interface{}) {
// Retrieve the stack infos
_, file, line, ok := runtime.Caller(1)
if !ok {
file = "<unknown>"
line = -1
} else {
file = file[strings.LastIndex(file, "/")+1:]
}
fmt.Fprintf(Stderr, "[%d] [debug] %s:%d ", os.Getpid(), file, line)
fmt.Fprintf(Stderr, format, a...)
fmt.Fprintln(Stderr)
}
181 changes: 169 additions & 12 deletions defaultHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
)

type (
HashValue map[string][]byte
HashHash map[string]HashValue
HashSub map[string][]*ChannelWriter
HashBrStack map[string]*Stack
HashValue map[string][]byte
HashHash map[string]HashValue
HashSub map[string][]*ChannelWriter
HashBrStack map[string]*Stack
HashOrderedSet map[string]*OrderedSet
)

type Database struct {
Expand All @@ -23,15 +24,18 @@ type Database struct {
brstack HashBrStack

sub HashSub

orderedSet HashOrderedSet
}

func NewDatabase(parent *Database) *Database {
db := &Database{
values: make(HashValue),
sub: make(HashSub),
brstack: make(HashBrStack),
children: map[int]*Database{},
parent: parent,
values: make(HashValue),
sub: make(HashSub),
brstack: make(HashBrStack),
children: map[int]*Database{},
parent: parent,
orderedSet: make(HashOrderedSet),
}
db.children[0] = db
return db
Expand Down Expand Up @@ -126,6 +130,12 @@ func (h *DefaultHandler) Lrange(key string, start, stop int) ([][]byte, error) {
}
}

if stop < 0 {
if stop = h.brstack[key].Len() + stop; stop < 0 {
stop = 0
}
}

var ret [][]byte
for i := start; i <= stop; i++ {
if val := h.brstack[key].GetIndex(i); val != nil {
Expand Down Expand Up @@ -234,6 +244,9 @@ func (h *DefaultHandler) Hset(key, subkey string, value []byte) (int, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}
if h.hvalues == nil {
h.hvalues = make(HashHash)
}
if _, exists := h.hvalues[key]; !exists {
h.hvalues[key] = make(HashValue)
ret = 1
Expand Down Expand Up @@ -281,16 +294,21 @@ func (h *DefaultHandler) Del(key string, keys ...string) (int, error) {
delete(h.values, k)
count++
}
if _, exists := h.hvalues[key]; exists {
if _, exists := h.hvalues[k]; exists {
delete(h.hvalues, k)
count++
}

if _, exists := h.brstack[k]; exists {
delete(h.brstack, k)
count++
}
}
return count, nil
}

func (h *DefaultHandler) Ping() (*StatusReply, error) {
return &StatusReply{code: "PONG"}, nil
return &StatusReply{Code: "PONG"}, nil
}

func (h *DefaultHandler) Subscribe(channels ...[]byte) (*MultiChannelWriter, error) {
Expand Down Expand Up @@ -353,7 +371,7 @@ func (h *DefaultHandler) Select(key string) error {
h.dbs[h.currentDb] = h.Database
h.currentDb = index
if _, exists := h.dbs[index]; !exists {
println("DB not exits, create ", index)
fmt.Println(Stderr, "DB not exits, create ", index)
h.dbs[index] = NewDatabase(nil)
}
h.Database = h.dbs[index]
Expand All @@ -364,6 +382,145 @@ func (h *DefaultHandler) Monitor() (*MonitorReply, error) {
return &MonitorReply{}, nil
}

var lock = make(chan bool, 1)

func (h *DefaultHandler) Incr(key string) (int, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

lock <- true

temp, _ := strconv.Atoi(string(h.values[key]))
temp = temp + 1
h.values[key] = []byte(strconv.Itoa(temp))

<-lock

return temp, nil
}

func (h *DefaultHandler) Decr(key string) (int, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

lock <- true

temp, _ := strconv.Atoi(string(h.values[key]))
temp = temp - 1
h.values[key] = []byte(strconv.Itoa(temp))

<-lock

return temp, nil
}

func (h *DefaultHandler) Expire(key, after string) (int, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

d, _ := strconv.Atoi(after)

time.AfterFunc(time.Duration(d)*time.Second, func() {
h.Del(key)
})

return 1, nil
}

func (h *DefaultHandler) Exists(key string) (int, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

_, exists := h.values[key]
if exists {
return 1, nil
} else {
return 0, nil
}
}

func (h *DefaultHandler) Zadd(key string, score int, value []byte, values ...[]byte) (int, error) {
values = append([][]byte{value}, values...)

if h.Database == nil {
h.Database = NewDatabase(nil)
}

if _, exists := h.orderedSet[key]; !exists {
h.orderedSet[key] = NewOrderedSet()
}

ctr := 0
for _, v := range values {
ctr = ctr + h.orderedSet[key].Add(score, v)
}

return ctr, nil
}

func (h *DefaultHandler) Zrange(key string, min int, max int) ([][]byte, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

if _, exists := h.orderedSet[key]; !exists {
return [][]byte{}, nil
}

r := h.orderedSet[key].Range(min, max)

return r, nil
}

func (h *DefaultHandler) Zrangebyscore(key string, min int, max int) ([][]byte, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

if _, exists := h.orderedSet[key]; !exists {
return [][]byte{}, nil
}

r := h.orderedSet[key].RangeByScore(min, max)

return r, nil
}

func (h *DefaultHandler) Zrem(key string, value []byte, values ...[]byte) (int, error) {
values = append([][]byte{value}, values...)

if h.Database == nil {
h.Database = NewDatabase(nil)
}

if _, exists := h.orderedSet[key]; !exists {
return 0, nil
}

ctr := 0
for _, v := range values {
ctr += h.orderedSet[key].Rem(v)
}

return ctr, nil
}

func (h *DefaultHandler) Zremrangebyscore(key string, min int, max int) (int, error) {
if h.Database == nil {
h.Database = NewDatabase(nil)
}

if _, exists := h.orderedSet[key]; !exists {
return 0, nil
}

return h.orderedSet[key].RemRangeByScore(min, max), nil
}

func NewDefaultHandler() *DefaultHandler {
db := NewDatabase(nil)
ret := &DefaultHandler{
Expand Down
5 changes: 3 additions & 2 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package main

import (
"fmt"
redis "github.com/dotcloud/go-redis-server"

redis "github.com/platinasystems/go-redis-server"
)

type MyHandler struct {
Expand Down Expand Up @@ -45,7 +46,7 @@ func main() {
if err := srv.RegisterFct("test2", Test2); err != nil {
panic(err)
}
if err := srv.ListenAndServe(); err != nil {
if err := srv.Start(); err != nil {
panic(err)
}
}
4 changes: 2 additions & 2 deletions example/simple/main.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package main

import (
redis "github.com/dotcloud/go-redis-server"
redis "github.com/platinasystems/go-redis-server"
)

func main() {
server, err := redis.NewServer(redis.DefaultConfig())
if err != nil {
panic(err)
}
if err := server.ListenAndServe(); err != nil {
if err := server.Start(); err != nil {
panic(err)
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module github.com/platinasystems/go-redis-server
3 changes: 3 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ func (srv *Server) Register(name string, fn HandlerFn) {
}

func (srv *Server) Apply(r *Request) (ReplyWriter, error) {
srv.Lock()
defer srv.Unlock()

if srv == nil || srv.methods == nil {
Debugf("The method map is uninitialized")
return ErrMethodNotSupported, nil
Expand Down
2 changes: 2 additions & 0 deletions handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ func TestEmptyHandler(t *testing.T) {
c := make(chan struct{})
defer close(c)
srv := &Server{}
defer srv.Close()
reply, err := srv.ApplyString(&Request{})
if err != nil {
t.Fatalf("Unexpected error: %s", err)
Expand All @@ -23,6 +24,7 @@ func TestCustomHandler(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer srv.Close()
srv.Register("GET", func(r *Request) (ReplyWriter, error) {
return &BulkReply{value: []byte("42")}, nil
})
Expand Down
Loading