commit afaeaefb5857bd92ce4afe75d43022c738dd75bc
parent c1ebe2bda9bdc77e0639e993f8d043713f2a7692
Author: Matsuda Kenji <info@mtkn.jp>
Date: Fri, 29 Dec 2023 07:40:53 +0900
change getReq.
separatin ReqPool from Server
Diffstat:
2 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/server.go b/server.go
@@ -116,7 +116,7 @@ func (s *Server) runListener(ctx context.Context) {
defer close(rc)
for {
select {
- case rc <- s.getReq():
+ case rc <- getReq(s.r, s.rPool, s.chatty9P):
case <-ctx.Done():
return
}
@@ -134,6 +134,14 @@ func (s *Server) runSpeaker(ctx context.Context) {
for {
select {
case r := <-rc:
+ // free tag.
+ if r.pool == nil {
+ if e, ok := r.Ofcall.(*RError); !ok || e.Ename != ErrDupTag {
+ panic("r.pool is nil and error is not EDupTag")
+ }
+ } else {
+ r.pool.delete(r.Tag)
+ }
_, err := s.w.Write(r.Ofcall.marshal())
if err != nil {
select {
@@ -155,35 +163,35 @@ func (s *Server) runSpeaker(ctx context.Context) {
// Any error it encountered is embedded into the Req struct.
// This function is called only by the server's listener goroutine,
// and does not need to lock s.r.
-func (s *Server) getReq() *Req {
- ifcall, err := RecvMsg(s.r)
+func getReq(r io.Reader, rp *ReqPool, chatty bool) *Req {
+ ifcall, err := RecvMsg(r)
if err != nil {
if err == io.EOF {
return &Req{listenErr: err}
}
return &Req{listenErr: fmt.Errorf("readMsg: %v", err)}
}
- req, err := s.rPool.add(ifcall.GetTag())
+ req, err := rp.add(ifcall.GetTag())
if err != nil {
// duplicate tag: cons up a fake Req
req := new(Req)
- req.Srv = s
+ //req.Srv = s
req.Ifcall = ifcall
req.listenErr = ErrDupTag
req.done = make(chan struct{})
- if s.chatty9P {
+ if chatty {
fmt.Fprintf(os.Stderr, "<-- %v\n", req.Ifcall)
}
return req
}
- req.Srv = s
+ //req.Srv = s
req.Tag = ifcall.GetTag()
req.Ifcall = ifcall
req.done = make(chan struct{})
if ifcall, ok := req.Ifcall.(*TFlush); ok {
- req.Oldreq, _ = s.rPool.lookup(ifcall.Oldtag)
+ req.Oldreq, _ = rp.lookup(ifcall.Oldtag)
}
- if s.chatty9P {
+ if chatty {
fmt.Fprintf(os.Stderr, "<-- %v\n", req.Ifcall)
}
return req
@@ -1256,13 +1264,6 @@ func respond(ctx context.Context, s *Server) {
return
}
r.Ofcall.SetTag(r.Tag)
- // free tag.
- if r.pool == nil && r.err != ErrDupTag {
- panic("ReqPool is nil but err is not EDupTag")
- }
- if r.pool != nil {
- r.pool.delete(r.Tag)
- }
select {
case s.speakChan <- r:
if s.chatty9P {
diff --git a/server2_test.go b/server2_test.go
@@ -65,6 +65,7 @@ func TestRunSpeaker(t *testing.T) {
defer rFile.Close()
r, w := io.Pipe()
s := &Server{w: w}
+ rp := newReqPool()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
s.runSpeaker(ctx)
@@ -79,7 +80,11 @@ func TestRunSpeaker(t *testing.T) {
if err != nil {
t.Fatalf("unmarshal %v", err)
}
- s.speakChan <- &Req{Ofcall: msg, speakErrChan: make(chan error)}
+ s.speakChan <- &Req{
+ Ofcall: msg,
+ speakErrChan: make(chan error),
+ pool: rp,
+ }
got := make([]byte, len(want))
_, err = io.ReadFull(r, got)
if err != nil {
@@ -105,7 +110,7 @@ func TestGetReq(t *testing.T) {
defer tFile2.Close()
s := &Server{r: tFile, rPool: newReqPool()}
for {
- got := s.getReq()
+ got := getReq(s.r, s.rPool, s.chatty9P)
if got.listenErr == io.EOF {
break
} else if got.listenErr != nil {
@@ -115,9 +120,6 @@ func TestGetReq(t *testing.T) {
if err != nil {
t.Fatalf("recvmsg: %v", err)
}
- if got.Srv != s {
- t.Errorf("r.Srv not set properly.")
- }
if got.Tag != wantMsg.GetTag() {
t.Errorf("r.Tag: want: %v, got: %v", wantMsg.GetTag(), got.Tag)
}