1
0
mirror of https://github.com/redis/go-redis.git synced 2025-07-29 17:41:15 +03:00

Fix ReceiveMessage to work without any subscriptions.

This commit is contained in:
Vladimir Mihailenco
2017-02-08 11:24:09 +02:00
parent ba0b485159
commit ce4fd8b677
18 changed files with 164 additions and 129 deletions

View File

@ -26,13 +26,17 @@ type Reader struct {
buf []byte
}
func NewReader(rd io.Reader) *Reader {
func NewReader(rd io.Reader, buf []byte) *Reader {
return &Reader{
src: bufio.NewReader(rd),
buf: make([]byte, 0, bufferSize),
buf: buf,
}
}
func (r *Reader) Reset(rd io.Reader) {
r.src.Reset(rd)
}
func (p *Reader) PeekBuffered() []byte {
if n := p.src.Buffered(); n != 0 {
b, _ := p.src.Peek(n)
@ -42,7 +46,12 @@ func (p *Reader) PeekBuffered() []byte {
}
func (p *Reader) ReadN(n int) ([]byte, error) {
return readN(p.src, p.buf, n)
b, err := readN(p.src, p.buf, n)
if err != nil {
return nil, err
}
p.buf = b
return b, nil
}
func (p *Reader) ReadLine() ([]byte, error) {
@ -72,11 +81,11 @@ func (p *Reader) ReadReply(m MultiBulkParse) (interface{}, error) {
case ErrorReply:
return nil, ParseErrorReply(line)
case StatusReply:
return parseStatusValue(line)
return parseStatusValue(line), nil
case IntReply:
return parseInt(line[1:], 10, 64)
case StringReply:
return p.readBytesValue(line)
return p.readTmpBytesValue(line)
case ArrayReply:
n, err := parseArrayLen(line)
if err != nil {
@ -111,9 +120,9 @@ func (p *Reader) ReadTmpBytesReply() ([]byte, error) {
case ErrorReply:
return nil, ParseErrorReply(line)
case StringReply:
return p.readBytesValue(line)
return p.readTmpBytesValue(line)
case StatusReply:
return parseStatusValue(line)
return parseStatusValue(line), nil
default:
return nil, fmt.Errorf("redis: can't parse string reply: %.100q", line)
}
@ -210,7 +219,7 @@ func (p *Reader) ReadScanReply() ([]string, uint64, error) {
return keys, cursor, err
}
func (p *Reader) readBytesValue(line []byte) ([]byte, error) {
func (p *Reader) readTmpBytesValue(line []byte) ([]byte, error) {
if isNilReply(line) {
return nil, internal.Nil
}
@ -297,8 +306,8 @@ func ParseErrorReply(line []byte) error {
return internal.RedisError(string(line[1:]))
}
func parseStatusValue(line []byte) ([]byte, error) {
return line[1:], nil
func parseStatusValue(line []byte) []byte {
return line[1:]
}
func parseArrayLen(line []byte) (int64, error) {

View File

@ -5,27 +5,27 @@ import (
"strings"
"testing"
"gopkg.in/redis.v5/internal/proto"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"gopkg.in/redis.v5/internal/proto"
)
var _ = Describe("Reader", func() {
It("should read n bytes", func() {
data, err := proto.NewReader(strings.NewReader("ABCDEFGHIJKLMNO")).ReadN(10)
data, err := proto.NewReader(strings.NewReader("ABCDEFGHIJKLMNO"), nil).ReadN(10)
Expect(err).NotTo(HaveOccurred())
Expect(len(data)).To(Equal(10))
Expect(string(data)).To(Equal("ABCDEFGHIJ"))
data, err = proto.NewReader(strings.NewReader(strings.Repeat("x", 8192))).ReadN(6000)
data, err = proto.NewReader(strings.NewReader(strings.Repeat("x", 8192)), nil).ReadN(6000)
Expect(err).NotTo(HaveOccurred())
Expect(len(data)).To(Equal(6000))
})
It("should read lines", func() {
p := proto.NewReader(strings.NewReader("$5\r\nhello\r\n"))
p := proto.NewReader(strings.NewReader("$5\r\nhello\r\n"), nil)
data, err := p.ReadLine()
Expect(err).NotTo(HaveOccurred())
@ -59,11 +59,11 @@ func BenchmarkReader_ParseReply_Slice(b *testing.B) {
}
func benchmarkParseReply(b *testing.B, reply string, m proto.MultiBulkParse, wanterr bool) {
buf := &bytes.Buffer{}
buf := new(bytes.Buffer)
for i := 0; i < b.N; i++ {
buf.WriteString(reply)
}
p := proto.NewReader(buf)
p := proto.NewReader(buf, nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {

View File

@ -8,11 +8,13 @@ import (
const bufferSize = 4096
type WriteBuffer struct{ b []byte }
type WriteBuffer struct {
b []byte
}
func NewWriteBuffer() *WriteBuffer {
func NewWriteBuffer(b []byte) *WriteBuffer {
return &WriteBuffer{
b: make([]byte, 0, bufferSize),
b: b,
}
}

View File

@ -4,17 +4,17 @@ import (
"testing"
"time"
"gopkg.in/redis.v5/internal/proto"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"gopkg.in/redis.v5/internal/proto"
)
var _ = Describe("WriteBuffer", func() {
var buf *proto.WriteBuffer
BeforeEach(func() {
buf = proto.NewWriteBuffer()
buf = proto.NewWriteBuffer(nil)
})
It("should reset", func() {
@ -53,7 +53,7 @@ var _ = Describe("WriteBuffer", func() {
})
func BenchmarkWriteBuffer_Append(b *testing.B) {
buf := proto.NewWriteBuffer()
buf := proto.NewWriteBuffer(nil)
args := []interface{}{"hello", "world", "foo", "bar"}
for i := 0; i < b.N; i++ {