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.
@@ -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))
@@ -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
- // mux is the mux to handle calls
20
- mux Mux
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, mux Mux) *ServerRPC {
39
+ func NewServerRPC(ctx context.Context, invoker Invoker) *ServerRPC {
40
40
  rpc := &ServerRPC{
41
- dataCh: make(chan []byte, 5),
42
- mux: mux,
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.mux.InvokeMethod(serviceID, methodID, strm)
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
- // mux is the srpc mux
13
- mux Mux
12
+ // invoker is the method invoker
13
+ invoker Invoker
14
14
  }
15
15
 
16
16
  // NewServer constructs a new SRPC server.
17
- func NewServer(mux Mux) *Server {
17
+ func NewServer(invoker Invoker) *Server {
18
18
  return &Server{
19
- mux: mux,
19
+ invoker: invoker,
20
20
  }
21
21
  }
22
22
 
23
- // GetMux returns the mux.
24
- func (s *Server) GetMux() Mux {
25
- return s.mux
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.mux)
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)