From 7333f0a0d2e17ee697b3849be08238c33c378966 Mon Sep 17 00:00:00 2001 From: Harmen Date: Mon, 15 Jan 2018 15:47:22 +0100 Subject: [PATCH] m.redigo(), to avoid a TCP connection in Lua Not public to keep the redigo stuff internal --- cmd_scripting.go | 9 +-------- miniredis.go | 10 ++++++++++ miniredis_test.go | 18 ++++++++++++++++++ server/server.go | 35 ++++++++++++++++++++--------------- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/cmd_scripting.go b/cmd_scripting.go index 2e645d43..f7a01fed 100644 --- a/cmd_scripting.go +++ b/cmd_scripting.go @@ -3,12 +3,10 @@ package miniredis import ( "crypto/sha1" "encoding/hex" - "fmt" "io" "strconv" "strings" - "github.com/garyburd/redigo/redis" lua "github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua/parse" @@ -25,12 +23,7 @@ func (m *Miniredis) runLuaScript(c *server.Peer, script string, args []string) { l := lua.NewState() defer l.Close() - // create a redis client for redis.call - conn, err := redis.Dial("tcp", m.srv.Addr().String()) - if err != nil { - c.WriteError(fmt.Sprintf("ERR Redis error: %v", err.Error())) - return - } + conn := m.redigo() defer conn.Close() // set global variable KEYS diff --git a/miniredis.go b/miniredis.go index 9a016f0f..0370d0bd 100644 --- a/miniredis.go +++ b/miniredis.go @@ -16,10 +16,13 @@ package miniredis import ( "fmt" + "net" "strconv" "sync" "time" + redigo "github.com/garyburd/redigo/redis" + "github.com/alicebob/miniredis/server" ) @@ -237,6 +240,13 @@ func (m *Miniredis) FastForward(duration time.Duration) { } } +// redigo returns a redigo.Conn, connected using net.Pipe +func (m *Miniredis) redigo() redigo.Conn { + c1, c2 := net.Pipe() + m.srv.ServeConn(c1) + return redigo.NewConn(c2, 0, 0) +} + // Dump returns a text version of the selected DB, usable for debugging. func (m *Miniredis) Dump() string { m.Lock() diff --git a/miniredis_test.go b/miniredis_test.go index bac7ddd6..a79aa23f 100644 --- a/miniredis_test.go +++ b/miniredis_test.go @@ -211,3 +211,21 @@ func TestExpireWithFastForward(t *testing.T) { s.FastForward(5 * time.Second) equals(t, 1, len(s.Keys())) } + +func TestRedigo(t *testing.T) { + s, err := Run() + ok(t, err) + + r := s.redigo() + defer r.Close() + + _, err = r.Do("SELECT", 2) + ok(t, err) + + _, err = r.Do("SET", "foo", "bar") + ok(t, err) + + v, err := redis.String(r.Do("GET", "foo")) + ok(t, err) + equals(t, "bar", v) +} diff --git a/server/server.go b/server/server.go index fb130afc..69ee67e3 100644 --- a/server/server.go +++ b/server/server.go @@ -54,24 +54,29 @@ func (s *Server) serve(l net.Listener) { if err != nil { return } - s.wg.Add(1) - go func() { - defer s.wg.Done() - defer conn.Close() - s.mu.Lock() - s.peers[conn] = struct{}{} - s.infoConns++ - s.mu.Unlock() - - s.servePeer(conn) - - s.mu.Lock() - delete(s.peers, conn) - s.mu.Unlock() - }() + s.ServeConn(conn) } } +// ServeConn handles a net.Conn. Nice with net.Pipe() +func (s *Server) ServeConn(conn net.Conn) { + s.wg.Add(1) + go func() { + defer s.wg.Done() + defer conn.Close() + s.mu.Lock() + s.peers[conn] = struct{}{} + s.infoConns++ + s.mu.Unlock() + + s.servePeer(conn) + + s.mu.Lock() + delete(s.peers, conn) + s.mu.Unlock() + }() +} + // Addr has the net.Addr struct func (s *Server) Addr() *net.TCPAddr { s.mu.Lock()