From f0475b635e947d015880c9fae8ea8e0c3af4c133 Mon Sep 17 00:00:00 2001 From: siddontang Date: Mon, 10 Nov 2014 13:09:37 +0800 Subject: [PATCH] client perform use coroutine hope improving performance --- server/client.go | 38 +++++++++++++++++++++++++++++++++++++- server/client_http.go | 1 + server/client_resp.go | 24 +++++++----------------- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/server/client.go b/server/client.go index d39241b..57abc8c 100644 --- a/server/client.go +++ b/server/client.go @@ -6,6 +6,7 @@ import ( "github.com/siddontang/go/sync2" "github.com/siddontang/ledisdb/ledis" "io" + "sync" "time" ) @@ -74,6 +75,13 @@ type client struct { script *ledis.Multi slaveListeningAddr string + + quit chan struct{} + done chan error + + wg sync.WaitGroup + + fc chan CommandFunc } func newClient(app *App) *client { @@ -85,9 +93,35 @@ func newClient(app *App) *client { // c.reqErr = make(chan error) + c.quit = make(chan struct{}) + c.done = make(chan error, 1) + c.fc = make(chan CommandFunc, 1) + + c.wg.Add(1) + go c.run() + return c } +func (c *client) close() { + close(c.quit) + + c.wg.Wait() +} + +func (c *client) run() { + defer c.wg.Done() + + for { + select { + case <-c.quit: + return + case f := <-c.fc: + c.done <- f(c) + } + } +} + func (c *client) perform() { var err error @@ -114,7 +148,9 @@ func (c *client) perform() { // }() // err = <-c.reqErr - err = exeCmd(c) + c.fc <- exeCmd + + err = <-c.done } } diff --git a/server/client_http.go b/server/client_http.go index 057ba6b..d039533 100644 --- a/server/client_http.go +++ b/server/client_http.go @@ -50,6 +50,7 @@ func newClientHTTP(app *App, w http.ResponseWriter, r *http.Request) { return } c.perform() + c.client.close() } func (c *httpClient) addr(r *http.Request) string { diff --git a/server/client_resp.go b/server/client_resp.go index cfcaf5d..b538f1a 100644 --- a/server/client_resp.go +++ b/server/client_resp.go @@ -56,6 +56,8 @@ func (c *respClient) run() { c.app.info.addClients(1) defer func() { + c.client.close() + c.app.info.addClients(-1) if e := recover(); e != nil { @@ -82,32 +84,20 @@ func (c *respClient) run() { }() kc := time.Duration(c.app.cfg.ConnKeepaliveInterval) * time.Second - done := make(chan error) for { if kc > 0 { c.conn.SetReadDeadline(time.Now().Add(kc)) } - // I still don't know why use goroutine can improve performance - // if someone knows and benchamrks with another different result without goroutine, please tell me - go func() { - reqData, err := c.readRequest() - if err == nil { - c.handleRequest(reqData) - } + reqData, err := c.readRequest() + if err == nil { + c.handleRequest(reqData) + } - done <- err - }() - - // reqData, err := c.readRequest() - // if err == nil { - // c.handleRequest(reqData) - // } - - err := <-done if err != nil { return } + if c.conn == nil { return }