mirror of https://github.com/tidwall/redcon.git
minor optimizations
This commit is contained in:
parent
142cd0b96f
commit
55f1a9cf23
111
redcon.go
111
redcon.go
|
@ -42,32 +42,40 @@ func ListenAndServe(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer ln.Close()
|
defer ln.Close()
|
||||||
|
if handler == nil {
|
||||||
|
handler = func(conn Conn, cmds [][]string) {}
|
||||||
|
}
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
for {
|
for {
|
||||||
conn, err := ln.Accept()
|
nc, err := ln.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wr := newWriter(conn)
|
tcpc := nc.(*net.TCPConn)
|
||||||
wrc := &connWriter{wr, conn.RemoteAddr().String()}
|
c := &conn{tcpc, newWriter(tcpc), tcpc.RemoteAddr().String()}
|
||||||
if accept != nil && !accept(wrc) {
|
if accept != nil && !accept(c) {
|
||||||
conn.Close()
|
c.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go func() {
|
go handle(c, &mu, handler, closed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func handle(c *conn, mu *sync.Mutex,
|
||||||
|
handler func(conn Conn, cmds [][]string),
|
||||||
|
closed func(conn Conn, err error)) {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
conn.Close()
|
c.conn.Close()
|
||||||
if closed != nil {
|
if closed != nil {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
closed(wrc, err)
|
closed(c, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
rd := newReader(conn)
|
rd := newReader(c.conn)
|
||||||
err = func() error {
|
err = func() error {
|
||||||
for {
|
for {
|
||||||
cmds, err := rd.ReadCommands()
|
cmds, err := rd.ReadCommands()
|
||||||
|
@ -75,70 +83,67 @@ func ListenAndServe(
|
||||||
if err, ok := err.(*errProtocol); ok {
|
if err, ok := err.(*errProtocol); ok {
|
||||||
// All protocol errors should attempt a response to
|
// All protocol errors should attempt a response to
|
||||||
// the client. Ignore errors.
|
// the client. Ignore errors.
|
||||||
wr.WriteError("ERR " + err.Error())
|
c.wr.WriteError("ERR " + err.Error())
|
||||||
wr.Flush()
|
c.wr.Flush()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(cmds) > 0 {
|
if len(cmds) > 0 {
|
||||||
if handler != nil {
|
handler(c, cmds)
|
||||||
handler(wrc, cmds)
|
|
||||||
}
|
}
|
||||||
}
|
if c.wr.err != nil {
|
||||||
if wr.err != nil {
|
if c.wr.err == errClosed {
|
||||||
if wr.err == errClosed {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return wr.err
|
return c.wr.err
|
||||||
}
|
}
|
||||||
if err := wr.Flush(); err != nil {
|
if err := c.wr.Flush(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type connWriter struct {
|
type conn struct {
|
||||||
wr *respWriter
|
conn *net.TCPConn
|
||||||
|
wr *writer
|
||||||
addr string
|
addr string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wrc *connWriter) Close() error {
|
func (c *conn) Close() error {
|
||||||
return wrc.wr.Close()
|
return c.wr.Close()
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) WriteString(str string) {
|
func (c *conn) WriteString(str string) {
|
||||||
wrc.wr.WriteString(str)
|
c.wr.WriteString(str)
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) WriteBulk(bulk string) {
|
func (c *conn) WriteBulk(bulk string) {
|
||||||
wrc.wr.WriteBulk(bulk)
|
c.wr.WriteBulk(bulk)
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) WriteInt(num int) {
|
func (c *conn) WriteInt(num int) {
|
||||||
wrc.wr.WriteInt(num)
|
c.wr.WriteInt(num)
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) WriteError(msg string) {
|
func (c *conn) WriteError(msg string) {
|
||||||
wrc.wr.WriteError(msg)
|
c.wr.WriteError(msg)
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) WriteArray(count int) {
|
func (c *conn) WriteArray(count int) {
|
||||||
wrc.wr.WriteMultiBulkStart(count)
|
c.wr.WriteMultiBulkStart(count)
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) WriteNull() {
|
func (c *conn) WriteNull() {
|
||||||
wrc.wr.WriteNull()
|
c.wr.WriteNull()
|
||||||
}
|
}
|
||||||
func (wrc *connWriter) RemoteAddr() string {
|
func (c *conn) RemoteAddr() string {
|
||||||
return wrc.addr
|
return c.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reader represents a RESP command reader.
|
// Reader represents a RESP command reader.
|
||||||
type respReader struct {
|
type respReader struct {
|
||||||
r io.Reader // base reader
|
r *net.TCPConn // base reader
|
||||||
b []byte // unprocessed bytes
|
b []byte // unprocessed bytes
|
||||||
a []byte // static read buffer
|
a []byte // static read buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReader returns a RESP command reader.
|
// NewReader returns a RESP command reader.
|
||||||
func newReader(r io.Reader) *respReader {
|
func newReader(r *net.TCPConn) *respReader {
|
||||||
return &respReader{
|
return &respReader{
|
||||||
r: r,
|
r: r,
|
||||||
a: make([]byte, 8192),
|
a: make([]byte, 8192),
|
||||||
|
@ -316,24 +321,24 @@ func (r *respReader) ReadCommands() ([][]string, error) {
|
||||||
|
|
||||||
var errClosed = errors.New("closed")
|
var errClosed = errors.New("closed")
|
||||||
|
|
||||||
type respWriter struct {
|
type writer struct {
|
||||||
w io.Writer
|
w *net.TCPConn
|
||||||
b []byte
|
b []byte
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWriter(w io.Writer) *respWriter {
|
func newWriter(w *net.TCPConn) *writer {
|
||||||
return &respWriter{w: w, b: make([]byte, 0, 256)}
|
return &writer{w: w, b: make([]byte, 0, 256)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) WriteNull() error {
|
func (w *writer) WriteNull() error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
w.b = append(w.b, '$', '-', '1', '\r', '\n')
|
w.b = append(w.b, '$', '-', '1', '\r', '\n')
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (w *respWriter) WriteMultiBulkStart(count int) error {
|
func (w *writer) WriteMultiBulkStart(count int) error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
@ -343,7 +348,7 @@ func (w *respWriter) WriteMultiBulkStart(count int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) WriteBulk(bulk string) error {
|
func (w *writer) WriteBulk(bulk string) error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
@ -355,7 +360,7 @@ func (w *respWriter) WriteBulk(bulk string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) Flush() error {
|
func (w *writer) Flush() error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
@ -370,7 +375,7 @@ func (w *respWriter) Flush() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) WriteMultiBulk(bulks []string) error {
|
func (w *writer) WriteMultiBulk(bulks []string) error {
|
||||||
if err := w.WriteMultiBulkStart(len(bulks)); err != nil {
|
if err := w.WriteMultiBulkStart(len(bulks)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -382,7 +387,7 @@ func (w *respWriter) WriteMultiBulk(bulks []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) WriteError(msg string) error {
|
func (w *writer) WriteError(msg string) error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
@ -392,7 +397,7 @@ func (w *respWriter) WriteError(msg string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) WriteString(msg string) error {
|
func (w *writer) WriteString(msg string) error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
@ -402,7 +407,7 @@ func (w *respWriter) WriteString(msg string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) WriteInt(num int) error {
|
func (w *writer) WriteInt(num int) error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
@ -412,7 +417,7 @@ func (w *respWriter) WriteInt(num int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *respWriter) Close() error {
|
func (w *writer) Close() error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue