func makeRequest(conn net.Conn, req *types.Request) (*types.Response, error) { // Write desired request err := types.WriteMessage(req, conn) if err != nil { return nil, err } // Write flush request err = types.WriteMessage(types.RequestFlush(), conn) if err != nil { return nil, err } // Read desired response var res = &types.Response{} err = types.ReadMessage(conn, res) if err != nil { return nil, err } // Read flush response var resFlush = &types.Response{} err = types.ReadMessage(conn, resFlush) if err != nil { return nil, err } if resFlush.Type != types.MessageType_Flush { return nil, errors.New(Fmt("Expected types.MessageType_Flush but got %v instead", resFlush.Type)) } return res, nil }
func makeRequest(conn net.Conn, req *types.Request) (*types.Response, error) { var bufWriter = bufio.NewWriter(conn) // Write desired request err := types.WriteMessage(req, bufWriter) if err != nil { return nil, err } err = types.WriteMessage(types.ToRequestFlush(), bufWriter) if err != nil { return nil, err } err = bufWriter.Flush() if err != nil { return nil, err } // Read desired response var res = &types.Response{} err = types.ReadMessage(conn, res) if err != nil { return nil, err } var resFlush = &types.Response{} err = types.ReadMessage(conn, resFlush) if err != nil { return nil, err } if _, ok := resFlush.Value.(*types.Response_Flush); !ok { return nil, errors.New(Fmt("Expected flush response but got something else: %v", reflect.TypeOf(resFlush))) } return res, nil }
func (cli *socketClient) recvResponseRoutine(conn net.Conn) { r := bufio.NewReader(conn) // Buffer reads for { var res = &types.Response{} err := types.ReadMessage(r, res) if err != nil { cli.StopForError(err) return } switch r := res.Value.(type) { case *types.Response_Exception: // XXX After setting cli.err, release waiters (e.g. reqres.Done()) cli.StopForError(errors.New(r.Exception.Error)) return default: // log.Debug("Received response", "responseType", reflect.TypeOf(res), "response", res) err := cli.didRecvResponse(res) if err != nil { cli.StopForError(err) return } } } }
func main() { conn, err := Connect("unix://test.sock") if err != nil { Exit(err.Error()) } // Read a bunch of responses go func() { counter := 0 for { var res = &types.Response{} err := types.ReadMessage(conn, res) if err != nil { Exit(err.Error()) } counter += 1 if counter%1000 == 0 { fmt.Println("Read", counter) } } }() // Write a bunch of requests counter := 0 for i := 0; ; i++ { var bufWriter = bufio.NewWriter(conn) var req = types.RequestEcho("foobar") err := types.WriteMessage(req, bufWriter) if err != nil { Exit(err.Error()) } err = bufWriter.Flush() if err != nil { Exit(err.Error()) } counter += 1 if counter%1000 == 0 { fmt.Println("Write", counter) } } }
// Read requests from conn and deal with them func (s *SocketServer) handleRequests(closeConn chan error, conn net.Conn, responses chan<- *types.Response) { var count int var bufReader = bufio.NewReader(conn) for { var req = &types.Request{} err := types.ReadMessage(bufReader, req) if err != nil { if err == io.EOF { closeConn <- err } else { closeConn <- fmt.Errorf("Error reading message: %v", err.Error()) } return } s.appMtx.Lock() count++ s.handleRequest(req, responses) s.appMtx.Unlock() } }
// Read requests from conn and deal with them func handleRequests(mtx *sync.Mutex, app types.Application, closeConn chan error, conn net.Conn, responses chan<- *types.Response) { var count int var bufReader = bufio.NewReader(conn) for { var req = &types.Request{} err := types.ReadMessage(bufReader, req) if err != nil { if err == io.EOF { closeConn <- fmt.Errorf("Connection closed by client") } else { closeConn <- fmt.Errorf("Error in handleRequests: %v", err.Error()) } return } mtx.Lock() count++ handleRequest(app, req, responses) mtx.Unlock() } }
func TestStream(t *testing.T) { numAppendTxs := 200000 // Start the listener _, err := server.StartListener("tcp://127.0.0.1:46658", NewDummyApplication()) if err != nil { Exit(err.Error()) } // Connect to the socket conn, err := Connect("tcp://127.0.0.1:46658") if err != nil { Exit(err.Error()) } // Read response data done := make(chan struct{}) go func() { counter := 0 for { var res = &types.Response{} err := types.ReadMessage(conn, res) if err != nil { Exit(err.Error()) } // Process response switch res.Type { case types.MessageType_AppendTx: counter += 1 if res.Code != types.CodeType_OK { t.Error("AppendTx failed with ret_code", res.Code) } if counter > numAppendTxs { t.Fatal("Too many AppendTx responses") } t.Log("response", counter) if counter == numAppendTxs { go func() { time.Sleep(time.Second * 2) // Wait for a bit to allow counter overflow close(done) }() } case types.MessageType_Flush: // ignore default: t.Error("Unexpected response type", res.Type) } } }() // Write requests for counter := 0; counter < numAppendTxs; counter++ { // Send request var req = types.RequestAppendTx([]byte("test")) err := types.WriteMessage(req, conn) if err != nil { t.Fatal(err.Error()) } // Sometimes send flush messages if counter%123 == 0 { t.Log("flush") err := types.WriteMessage(types.RequestFlush(), conn) if err != nil { t.Fatal(err.Error()) } } } // Send final flush message err = types.WriteMessage(types.RequestFlush(), conn) if err != nil { t.Fatal(err.Error()) } <-done }