commit 11053d7793b1f0299e8fbc104ef1d02d176bc0eb
parent 7d78089531ea3268e91a69014d9f72c7e3f616d0
Author: Matsuda Kenji <info@mtkn.jp>
Date: Mon, 2 Oct 2023 11:27:33 +0900
change Client.Version
Diffstat:
| M | client.go | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
| M | client_test.go | | | 14 | ++++++++------ |
2 files changed, 60 insertions(+), 30 deletions(-)
diff --git a/client.go b/client.go
@@ -80,47 +80,75 @@ func (c *Client) runSpeaker(ctx context.Context, w io.Writer) (chan<- Msg, <-cha
return mc, ec
}
-func transact(ctx context.Context, w io.Writer, r io.Reader, tmsg Msg) (<-chan Msg, error) {
- if err := send(tmsg, w); err != nil {
- return nil, fmt.Errorf("send: %v", err)
- }
- mc := make(chan Msg)
+func transact(ctx context.Context, w io.Writer, r io.Reader, tmsg Msg) (<-chan Msg, <-chan error) {
+ err := send(tmsg, w)
+ rmsgc := make(chan Msg, 1)
+ errc := make(chan error, 1)
go func() {
- defer close(mc)
- rmc := make(chan Msg)
- var err error
+ defer close(rmsgc)
+ defer close(errc)
+ if err != nil {
+ errc <- err
+ return
+ }
+
+ rmsgc1 := make(chan Msg, 1)
+ errc1 := make(chan error, 1)
+ // TODO: cancel recv() with ctx.Done()
go func() {
- defer close(rmc)
- var rmsg Msg
- rmsg, err = recv(r)
+ defer close(rmsgc1)
+ defer close(errc1)
+ rmsg, err := recv(r)
if err != nil {
+ errc1 <- err
return
}
- rmc <- rmsg
+ rmsgc1 <- rmsg
}()
select {
- case rmsg := <-rmc:
- mc <- rmsg
+ case rmsg := <-rmsgc1:
+ rmsgc <- rmsg
+ case err := <-errc1:
+ errc <- err
case <-ctx.Done():
- return
+ errc <- fmt.Errorf("wait rmsg: %w", ctx.Err())
}
}()
- return mc, nil
+ return rmsgc, errc
}
-func (c *Client) Version(mSize uint32, version string) (<-chan *RVersion, error) {
+func (c *Client) Version(ctx context.Context, mSize uint32, version string) (<-chan *RVersion, <-chan error) {
tmsg := &TVersion{
tag: ^uint16(0),
mSize: mSize,
version: version,
}
- rmsgc, err := transact(context.TODO(), c.writer, c.reader, tmsg)
- if err != nil {
- return nil, err
- }
- rversionc := make(chan *RVersion)
+ rmsgc, errc := transact(ctx, c.writer, c.reader, tmsg)
+ rmsgc1 := make(chan *RVersion, 1)
+ errc1 := make(chan error, 1)
go func() {
- rversionc<- (<-rmsgc).(*RVersion)
+ defer close(rmsgc1)
+ defer close(errc1)
+ select {
+ case rmsg := <-rmsgc:
+ switch rmsg := rmsg.(type) {
+ case *RVersion:
+ rmsgc1<- rmsg
+ case *RError:
+ errc1<- rmsg.ename
+ default:
+ panic(fmt.Errorf("invalid R message: %v", rmsg))
+ }
+ case err := <- errc:
+ errc1 <- err
+ case <- ctx.Done():
+ errc1 <- fmt.Errorf("wait transact: %w", ctx.Err())
+ }
}()
- return rversionc, nil
+ return rmsgc1, errc1
+}
+
+func (c *Client) Auth(ctx context.Context, afid uint32, uname, aname string) (<-chan *RAuth, <-chan error) {
+// tmsg := &TAuth{afid: afid, uname: uname}
+ return nil, nil
}
\ No newline at end of file
diff --git a/client_test.go b/client_test.go
@@ -1,6 +1,7 @@
package lib9p
import (
+ "context"
"io"
"reflect"
"testing"
@@ -26,19 +27,20 @@ func TestServerVersion(t *testing.T) {
}
for _, test := range tests {
- t.Logf("%v\n", test)
cr, sw := io.Pipe()
sr, cw := io.Pipe()
server := NewServer(fsys, mSize, sr, sw)
client := NewClient(mSize, "kenji", cr, cw)
go server.Serve()
- rvc, err := client.Version(test.mSize, test.version)
- if err != nil {
- t.Fatal(err)
- }
+ rvc, ec := client.Version(context.TODO(), test.mSize, test.version)
- got := <-rvc
+ var got *RVersion
+ select {
+ case got = <-rvc:
+ case err := <-ec:
+ t.Error(err)
+ }
if !reflect.DeepEqual(got, test.want) {
t.Errorf("%s: want %v, get %v\n", test.name, test.want, got)
}