starpc 0.10.6 → 0.10.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -8
- package/dist/echo/echo.pb.d.ts +5 -5
- package/dist/echo/echo.pb.js +20 -20
- package/dist/rpcstream/rpcstream.pb.d.ts +7 -7
- package/dist/rpcstream/rpcstream.pb.js +39 -64
- package/dist/srpc/rpcproto.pb.d.ts +6 -6
- package/dist/srpc/rpcproto.pb.js +38 -75
- package/e2e/e2e_test.go +0 -7
- package/echo/echo.pb.ts +88 -144
- package/go.mod +9 -10
- package/go.sum +19 -21
- package/package.json +1 -1
- package/srpc/handler.go +11 -4
- package/srpc/mux.go +40 -4
- package/srpc/muxed-conn.go +7 -2
- package/srpc/rpcproto.pb.ts +183 -273
- package/srpc/rwc-conn.go +229 -0
- package/srpc/server-rpc.go +6 -6
- package/srpc/server.go +8 -8
package/srpc/rwc-conn.go
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
package srpc
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"io"
|
|
6
|
+
"net"
|
|
7
|
+
"os"
|
|
8
|
+
"sync"
|
|
9
|
+
"time"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
// connPktSize is the size of the buffers to use for packets for the RwcConn.
|
|
13
|
+
const connPktSize = 2048
|
|
14
|
+
|
|
15
|
+
// RwcConn implements a Conn with a buffered ReadWriteCloser.
|
|
16
|
+
type RwcConn struct {
|
|
17
|
+
// ctx is the context
|
|
18
|
+
ctx context.Context
|
|
19
|
+
// ctxCancel is the context canceler
|
|
20
|
+
ctxCancel context.CancelFunc
|
|
21
|
+
// rwc is the read-write-closer
|
|
22
|
+
rwc io.ReadWriteCloser
|
|
23
|
+
// laddr is the local addr
|
|
24
|
+
laddr net.Addr
|
|
25
|
+
// raddr is the remote addr
|
|
26
|
+
raddr net.Addr
|
|
27
|
+
|
|
28
|
+
ar sync.Pool // packet arena
|
|
29
|
+
rd time.Time // read deadline
|
|
30
|
+
wd time.Time // write deadline
|
|
31
|
+
packetCh chan []byte // packet ch
|
|
32
|
+
closeErr error
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// NewRwcConn constructs a new packet conn and starts the rx pump.
|
|
36
|
+
func NewRwcConn(
|
|
37
|
+
ctx context.Context,
|
|
38
|
+
rwc io.ReadWriteCloser,
|
|
39
|
+
laddr, raddr net.Addr,
|
|
40
|
+
bufferPacketN int,
|
|
41
|
+
) *RwcConn {
|
|
42
|
+
ctx, ctxCancel := context.WithCancel(ctx)
|
|
43
|
+
if bufferPacketN <= 0 {
|
|
44
|
+
bufferPacketN = 10
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
c := &RwcConn{
|
|
48
|
+
ctx: ctx,
|
|
49
|
+
ctxCancel: ctxCancel,
|
|
50
|
+
rwc: rwc,
|
|
51
|
+
laddr: laddr,
|
|
52
|
+
raddr: raddr,
|
|
53
|
+
packetCh: make(chan []byte, bufferPacketN),
|
|
54
|
+
}
|
|
55
|
+
go func() {
|
|
56
|
+
_ = c.rxPump()
|
|
57
|
+
}()
|
|
58
|
+
return c
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// LocalAddr returns the local network address.
|
|
62
|
+
func (p *RwcConn) LocalAddr() net.Addr {
|
|
63
|
+
return p.laddr
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// RemoteAddr returns the bound remote network address.
|
|
67
|
+
func (p *RwcConn) RemoteAddr() net.Addr {
|
|
68
|
+
return p.raddr
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Read reads data from the connection.
|
|
72
|
+
// Read can be made to time out and return an error after a fixed
|
|
73
|
+
// time limit; see SetDeadline and SetReadDeadline.
|
|
74
|
+
func (p *RwcConn) Read(b []byte) (n int, err error) {
|
|
75
|
+
deadline := p.rd
|
|
76
|
+
ctx := p.ctx
|
|
77
|
+
if !deadline.IsZero() {
|
|
78
|
+
var ctxCancel context.CancelFunc
|
|
79
|
+
ctx, ctxCancel = context.WithDeadline(ctx, deadline)
|
|
80
|
+
defer ctxCancel()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
var pkt []byte
|
|
84
|
+
var ok bool
|
|
85
|
+
select {
|
|
86
|
+
case <-ctx.Done():
|
|
87
|
+
if !deadline.IsZero() {
|
|
88
|
+
return 0, os.ErrDeadlineExceeded
|
|
89
|
+
}
|
|
90
|
+
return 0, context.Canceled
|
|
91
|
+
case pkt, ok = <-p.packetCh:
|
|
92
|
+
if !ok {
|
|
93
|
+
err = p.closeErr
|
|
94
|
+
if err == nil {
|
|
95
|
+
err = io.EOF
|
|
96
|
+
}
|
|
97
|
+
return 0, err
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
pl := len(pkt)
|
|
102
|
+
copy(b, pkt)
|
|
103
|
+
p.ar.Put(&pkt)
|
|
104
|
+
if len(b) < pl {
|
|
105
|
+
return len(b), io.ErrShortBuffer
|
|
106
|
+
}
|
|
107
|
+
return pl, nil
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Write writes data to the connection.
|
|
111
|
+
func (p *RwcConn) Write(pkt []byte) (n int, err error) {
|
|
112
|
+
if len(pkt) == 0 {
|
|
113
|
+
return 0, nil
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
written := 0
|
|
117
|
+
for written < len(pkt) {
|
|
118
|
+
n, err = p.rwc.Write(pkt[written:])
|
|
119
|
+
written += n
|
|
120
|
+
if err != nil {
|
|
121
|
+
return written, err
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return written, nil
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// SetDeadline sets the read and write deadlines associated
|
|
128
|
+
// with the connection. It is equivalent to calling both
|
|
129
|
+
// SetReadDeadline and SetWriteDeadline.
|
|
130
|
+
//
|
|
131
|
+
// A deadline is an absolute time after which I/O operations
|
|
132
|
+
// fail instead of blocking. The deadline applies to all future
|
|
133
|
+
// and pending I/O, not just the immediately following call to
|
|
134
|
+
// Read or Write. After a deadline has been exceeded, the
|
|
135
|
+
// connection can be refreshed by setting a deadline in the future.
|
|
136
|
+
//
|
|
137
|
+
// If the deadline is exceeded a call to Read or Write or to other
|
|
138
|
+
// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
|
|
139
|
+
// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
|
|
140
|
+
// The error's Timeout method will return true, but note that there
|
|
141
|
+
// are other possible errors for which the Timeout method will
|
|
142
|
+
// return true even if the deadline has not been exceeded.
|
|
143
|
+
//
|
|
144
|
+
// An idle timeout can be implemented by repeatedly extending
|
|
145
|
+
// the deadline after successful ReadFrom or WriteTo calls.
|
|
146
|
+
//
|
|
147
|
+
// A zero value for t means I/O operations will not time out.
|
|
148
|
+
func (p *RwcConn) SetDeadline(t time.Time) error {
|
|
149
|
+
p.rd = t
|
|
150
|
+
p.wd = t
|
|
151
|
+
return nil
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// SetReadDeadline sets the deadline for future ReadFrom calls
|
|
155
|
+
// and any currently-blocked ReadFrom call.
|
|
156
|
+
// A zero value for t means ReadFrom will not time out.
|
|
157
|
+
func (p *RwcConn) SetReadDeadline(t time.Time) error {
|
|
158
|
+
p.rd = t
|
|
159
|
+
return nil
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// SetWriteDeadline sets the deadline for future WriteTo calls
|
|
163
|
+
// and any currently-blocked WriteTo call.
|
|
164
|
+
// Even if write times out, it may return n > 0, indicating that
|
|
165
|
+
// some of the data was successfully written.
|
|
166
|
+
// A zero value for t means WriteTo will not time out.
|
|
167
|
+
func (p *RwcConn) SetWriteDeadline(t time.Time) error {
|
|
168
|
+
p.wd = t
|
|
169
|
+
return nil
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Close closes the connection.
|
|
173
|
+
// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
|
|
174
|
+
func (p *RwcConn) Close() error {
|
|
175
|
+
return p.rwc.Close()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// getArenaBuf returns a buf from the packet arena with at least the given size
|
|
179
|
+
func (p *RwcConn) getArenaBuf(size int) []byte {
|
|
180
|
+
var buf []byte
|
|
181
|
+
bufp := p.ar.Get()
|
|
182
|
+
if bufp != nil {
|
|
183
|
+
buf = *bufp.(*[]byte)
|
|
184
|
+
}
|
|
185
|
+
if size != 0 {
|
|
186
|
+
if cap(buf) < size {
|
|
187
|
+
buf = make([]byte, size)
|
|
188
|
+
} else {
|
|
189
|
+
buf = buf[:size]
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
buf = buf[:cap(buf)]
|
|
193
|
+
}
|
|
194
|
+
return buf
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// rxPump receives messages from the underlying connection.
|
|
198
|
+
func (p *RwcConn) rxPump() (rerr error) {
|
|
199
|
+
defer func() {
|
|
200
|
+
p.closeErr = rerr
|
|
201
|
+
close(p.packetCh)
|
|
202
|
+
}()
|
|
203
|
+
|
|
204
|
+
for {
|
|
205
|
+
select {
|
|
206
|
+
case <-p.ctx.Done():
|
|
207
|
+
return p.ctx.Err()
|
|
208
|
+
default:
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
pktBuf := p.getArenaBuf(int(connPktSize))
|
|
212
|
+
n, err := p.rwc.Read(pktBuf)
|
|
213
|
+
if n == 0 {
|
|
214
|
+
p.ar.Put(&pktBuf)
|
|
215
|
+
} else {
|
|
216
|
+
select {
|
|
217
|
+
case <-p.ctx.Done():
|
|
218
|
+
return context.Canceled
|
|
219
|
+
case p.packetCh <- pktBuf[:n]:
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if err != nil {
|
|
223
|
+
return err
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// _ is a type assertion
|
|
229
|
+
var _ net.Conn = ((*RwcConn)(nil))
|
package/srpc/server-rpc.go
CHANGED
|
@@ -16,8 +16,8 @@ type ServerRPC struct {
|
|
|
16
16
|
ctxCancel context.CancelFunc
|
|
17
17
|
// writer is the writer to write messages to
|
|
18
18
|
writer Writer
|
|
19
|
-
//
|
|
20
|
-
|
|
19
|
+
// invoker is the rpc call invoker
|
|
20
|
+
invoker Invoker
|
|
21
21
|
// service is the rpc service
|
|
22
22
|
service string
|
|
23
23
|
// method is the rpc method
|
|
@@ -36,10 +36,10 @@ type ServerRPC struct {
|
|
|
36
36
|
|
|
37
37
|
// NewServerRPC constructs a new ServerRPC session.
|
|
38
38
|
// note: call SetWriter before handling any incoming messages.
|
|
39
|
-
func NewServerRPC(ctx context.Context,
|
|
39
|
+
func NewServerRPC(ctx context.Context, invoker Invoker) *ServerRPC {
|
|
40
40
|
rpc := &ServerRPC{
|
|
41
|
-
dataCh:
|
|
42
|
-
|
|
41
|
+
dataCh: make(chan []byte, 5),
|
|
42
|
+
invoker: invoker,
|
|
43
43
|
}
|
|
44
44
|
rpc.ctx, rpc.ctxCancel = context.WithCancel(ctx)
|
|
45
45
|
return rpc
|
|
@@ -165,7 +165,7 @@ func (r *ServerRPC) invokeRPC() {
|
|
|
165
165
|
// ctx := r.ctx
|
|
166
166
|
serviceID, methodID := r.service, r.method
|
|
167
167
|
strm := NewMsgStream(r.ctx, r.writer, r.dataCh)
|
|
168
|
-
ok, err := r.
|
|
168
|
+
ok, err := r.invoker.InvokeMethod(serviceID, methodID, strm)
|
|
169
169
|
if err == nil && !ok {
|
|
170
170
|
err = ErrUnimplemented
|
|
171
171
|
}
|
package/srpc/server.go
CHANGED
|
@@ -9,27 +9,27 @@ import (
|
|
|
9
9
|
|
|
10
10
|
// Server handles incoming RPC streams with a mux.
|
|
11
11
|
type Server struct {
|
|
12
|
-
//
|
|
13
|
-
|
|
12
|
+
// invoker is the method invoker
|
|
13
|
+
invoker Invoker
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// NewServer constructs a new SRPC server.
|
|
17
|
-
func NewServer(
|
|
17
|
+
func NewServer(invoker Invoker) *Server {
|
|
18
18
|
return &Server{
|
|
19
|
-
|
|
19
|
+
invoker: invoker,
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
//
|
|
24
|
-
func (s *Server)
|
|
25
|
-
return s.
|
|
23
|
+
// GetInvoker returns the invoker.
|
|
24
|
+
func (s *Server) GetInvoker() Invoker {
|
|
25
|
+
return s.invoker
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// HandleStream handles an incoming ReadWriteCloser stream.
|
|
29
29
|
func (s *Server) HandleStream(ctx context.Context, rwc io.ReadWriteCloser) error {
|
|
30
30
|
subCtx, subCtxCancel := context.WithCancel(ctx)
|
|
31
31
|
defer subCtxCancel()
|
|
32
|
-
serverRPC := NewServerRPC(subCtx, s.
|
|
32
|
+
serverRPC := NewServerRPC(subCtx, s.invoker)
|
|
33
33
|
prw := NewPacketReadWriter(rwc)
|
|
34
34
|
serverRPC.SetWriter(prw)
|
|
35
35
|
go prw.ReadPump(serverRPC.HandlePacket, serverRPC.HandleStreamClose)
|