starpc 0.33.0 → 0.33.3
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/echo/echo_srpc.pb.go +0 -26
- package/mock/mock_srpc.pb.go +0 -6
- package/package.json +1 -1
- package/srpc/client-rpc.go +32 -26
- package/srpc/common-rpc.go +79 -67
- package/srpc/server-rpc.go +25 -19
package/echo/echo_srpc.pb.go
CHANGED
|
@@ -224,32 +224,6 @@ type SRPCEchoerServer interface {
|
|
|
224
224
|
DoNothing(context.Context, *emptypb.Empty) (*emptypb.Empty, error)
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
type SRPCEchoerUnimplementedServer struct{}
|
|
228
|
-
|
|
229
|
-
func (s *SRPCEchoerUnimplementedServer) Echo(context.Context, *EchoMsg) (*EchoMsg, error) {
|
|
230
|
-
return nil, srpc.ErrUnimplemented
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
func (s *SRPCEchoerUnimplementedServer) EchoServerStream(*EchoMsg, SRPCEchoer_EchoServerStreamStream) error {
|
|
234
|
-
return srpc.ErrUnimplemented
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
func (s *SRPCEchoerUnimplementedServer) EchoClientStream(SRPCEchoer_EchoClientStreamStream) (*EchoMsg, error) {
|
|
238
|
-
return nil, srpc.ErrUnimplemented
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
func (s *SRPCEchoerUnimplementedServer) EchoBidiStream(SRPCEchoer_EchoBidiStreamStream) error {
|
|
242
|
-
return srpc.ErrUnimplemented
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
func (s *SRPCEchoerUnimplementedServer) RpcStream(SRPCEchoer_RpcStreamStream) error {
|
|
246
|
-
return srpc.ErrUnimplemented
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
func (s *SRPCEchoerUnimplementedServer) DoNothing(context.Context, *emptypb.Empty) (*emptypb.Empty, error) {
|
|
250
|
-
return nil, srpc.ErrUnimplemented
|
|
251
|
-
}
|
|
252
|
-
|
|
253
227
|
const SRPCEchoerServiceID = "echo.Echoer"
|
|
254
228
|
|
|
255
229
|
type SRPCEchoerHandler struct {
|
package/mock/mock_srpc.pb.go
CHANGED
|
@@ -47,12 +47,6 @@ type SRPCMockServer interface {
|
|
|
47
47
|
MockRequest(context.Context, *MockMsg) (*MockMsg, error)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
type SRPCMockUnimplementedServer struct{}
|
|
51
|
-
|
|
52
|
-
func (s *SRPCMockUnimplementedServer) MockRequest(context.Context, *MockMsg) (*MockMsg, error) {
|
|
53
|
-
return nil, srpc.ErrUnimplemented
|
|
54
|
-
}
|
|
55
|
-
|
|
56
50
|
const SRPCMockServiceID = "e2e.mock.Mock"
|
|
57
51
|
|
|
58
52
|
type SRPCMockHandler struct {
|
package/package.json
CHANGED
package/srpc/client-rpc.go
CHANGED
|
@@ -32,21 +32,26 @@ func (r *ClientRPC) Start(writer PacketWriter, writeFirstMsg bool, firstMsg []by
|
|
|
32
32
|
return context.Canceled
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
r.mtx.Lock()
|
|
36
|
-
defer r.mtx.Unlock()
|
|
37
|
-
defer r.bcast.Broadcast()
|
|
38
|
-
r.writer = writer
|
|
39
35
|
var firstMsgEmpty bool
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
var err error
|
|
37
|
+
r.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
38
|
+
r.writer = writer
|
|
39
|
+
|
|
40
|
+
if writeFirstMsg {
|
|
41
|
+
firstMsgEmpty = len(firstMsg) == 0
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
pkt := NewCallStartPacket(r.service, r.method, firstMsg, firstMsgEmpty)
|
|
45
|
+
err = writer.WritePacket(pkt)
|
|
46
|
+
if err != nil {
|
|
47
|
+
r.ctxCancel()
|
|
48
|
+
_ = writer.Close()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
broadcast()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
return err
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
// HandlePacketData handles an incoming unparsed message packet.
|
|
@@ -60,14 +65,14 @@ func (r *ClientRPC) HandlePacketData(data []byte) error {
|
|
|
60
65
|
|
|
61
66
|
// HandleStreamClose handles the stream closing optionally w/ an error.
|
|
62
67
|
func (r *ClientRPC) HandleStreamClose(closeErr error) {
|
|
63
|
-
r.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
r.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
r.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
69
|
+
if closeErr != nil && r.remoteErr == nil {
|
|
70
|
+
r.remoteErr = closeErr
|
|
71
|
+
}
|
|
72
|
+
r.dataClosed = true
|
|
73
|
+
r.ctxCancel()
|
|
74
|
+
broadcast()
|
|
75
|
+
})
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
// HandlePacket handles an incoming parsed message packet.
|
|
@@ -102,8 +107,9 @@ func (r *ClientRPC) Close() {
|
|
|
102
107
|
if r.writer != nil {
|
|
103
108
|
_ = r.WriteCancel()
|
|
104
109
|
}
|
|
105
|
-
|
|
106
|
-
r.
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
|
|
111
|
+
r.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
112
|
+
r.closeLocked(broadcast)
|
|
113
|
+
broadcast()
|
|
114
|
+
})
|
|
109
115
|
}
|
package/srpc/common-rpc.go
CHANGED
|
@@ -3,7 +3,6 @@ package srpc
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
5
|
"io"
|
|
6
|
-
"sync"
|
|
7
6
|
|
|
8
7
|
"github.com/aperturerobotics/util/broadcast"
|
|
9
8
|
"github.com/pkg/errors"
|
|
@@ -19,9 +18,7 @@ type commonRPC struct {
|
|
|
19
18
|
service string
|
|
20
19
|
// method is the rpc method
|
|
21
20
|
method string
|
|
22
|
-
//
|
|
23
|
-
mtx sync.Mutex
|
|
24
|
-
// bcast broadcasts when below fields change
|
|
21
|
+
// bcast guards below fields
|
|
25
22
|
bcast broadcast.Broadcast
|
|
26
23
|
// writer is the writer to write messages to
|
|
27
24
|
writer PacketWriter
|
|
@@ -45,21 +42,25 @@ func (c *commonRPC) Context() context.Context {
|
|
|
45
42
|
return c.ctx
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
// Wait waits for the RPC to finish.
|
|
45
|
+
// Wait waits for the RPC to finish (remote end closed the stream).
|
|
49
46
|
func (c *commonRPC) Wait(ctx context.Context) error {
|
|
50
47
|
for {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
var dataClosed bool
|
|
49
|
+
var err error
|
|
50
|
+
var waitCh <-chan struct{}
|
|
51
|
+
c.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
52
|
+
dataClosed, err = c.dataClosed, c.remoteErr
|
|
53
|
+
waitCh = getWaitCh()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
if dataClosed {
|
|
55
57
|
return err
|
|
56
58
|
}
|
|
57
|
-
|
|
58
|
-
c.mtx.Unlock()
|
|
59
|
+
|
|
59
60
|
select {
|
|
60
61
|
case <-ctx.Done():
|
|
61
62
|
return context.Canceled
|
|
62
|
-
case <-
|
|
63
|
+
case <-waitCh:
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
}
|
|
@@ -68,39 +69,48 @@ func (c *commonRPC) Wait(ctx context.Context) error {
|
|
|
68
69
|
//
|
|
69
70
|
// returns io.EOF if the stream ended without a packet.
|
|
70
71
|
func (c *commonRPC) ReadOne() ([]byte, error) {
|
|
71
|
-
var msg []byte
|
|
72
|
+
var msg *[]byte
|
|
72
73
|
var err error
|
|
73
74
|
var ctxDone bool
|
|
74
75
|
for {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
c.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
c.dataQueue
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if
|
|
94
|
-
err =
|
|
76
|
+
var waitCh <-chan struct{}
|
|
77
|
+
c.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
78
|
+
waitCh = getWaitCh()
|
|
79
|
+
|
|
80
|
+
if ctxDone && !c.dataClosed {
|
|
81
|
+
// context must have been canceled locally
|
|
82
|
+
c.closeLocked(broadcast)
|
|
83
|
+
err = context.Canceled
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if len(c.dataQueue) != 0 {
|
|
88
|
+
msgb := c.dataQueue[0]
|
|
89
|
+
msg = &msgb
|
|
90
|
+
c.dataQueue[0] = nil
|
|
91
|
+
c.dataQueue = c.dataQueue[1:]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if c.dataClosed || c.remoteErr != nil {
|
|
95
|
+
err = c.remoteErr
|
|
96
|
+
if err == nil {
|
|
97
|
+
err = io.EOF
|
|
98
|
+
}
|
|
95
99
|
}
|
|
96
|
-
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
if err != nil {
|
|
97
103
|
return nil, err
|
|
98
104
|
}
|
|
99
|
-
|
|
105
|
+
|
|
106
|
+
if msg != nil {
|
|
107
|
+
return *msg, nil
|
|
108
|
+
}
|
|
109
|
+
|
|
100
110
|
select {
|
|
101
111
|
case <-c.ctx.Done():
|
|
102
112
|
ctxDone = true
|
|
103
|
-
case <-
|
|
113
|
+
case <-waitCh:
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
116
|
}
|
|
@@ -116,17 +126,17 @@ func (c *commonRPC) WriteCallData(data []byte, complete bool, err error) error {
|
|
|
116
126
|
|
|
117
127
|
// HandleStreamClose handles the incoming stream closing w/ optional error.
|
|
118
128
|
func (c *commonRPC) HandleStreamClose(closeErr error) {
|
|
119
|
-
c.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
c.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
130
|
+
if closeErr != nil && c.remoteErr == nil {
|
|
131
|
+
c.remoteErr = closeErr
|
|
132
|
+
}
|
|
133
|
+
c.dataClosed = true
|
|
134
|
+
c.ctxCancel()
|
|
135
|
+
if c.writer != nil {
|
|
136
|
+
_ = c.writer.Close()
|
|
137
|
+
}
|
|
138
|
+
broadcast()
|
|
139
|
+
})
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
// HandleCallCancel handles the call cancel packet.
|
|
@@ -137,29 +147,31 @@ func (c *commonRPC) HandleCallCancel() error {
|
|
|
137
147
|
|
|
138
148
|
// HandleCallData handles the call data packet.
|
|
139
149
|
func (c *commonRPC) HandleCallData(pkt *CallData) error {
|
|
140
|
-
|
|
141
|
-
|
|
150
|
+
var err error
|
|
151
|
+
c.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
152
|
+
if c.dataClosed {
|
|
153
|
+
err = ErrCompleted
|
|
154
|
+
return
|
|
155
|
+
}
|
|
142
156
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
157
|
+
if data := pkt.GetData(); len(data) != 0 || pkt.GetDataIsZero() {
|
|
158
|
+
c.dataQueue = append(c.dataQueue, data)
|
|
159
|
+
}
|
|
146
160
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
complete := pkt.GetComplete()
|
|
162
|
+
if err := pkt.GetError(); len(err) != 0 {
|
|
163
|
+
complete = true
|
|
164
|
+
c.remoteErr = errors.New(err)
|
|
165
|
+
}
|
|
150
166
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
c.remoteErr = errors.New(err)
|
|
155
|
-
}
|
|
167
|
+
if complete {
|
|
168
|
+
c.dataClosed = true
|
|
169
|
+
}
|
|
156
170
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
171
|
+
broadcast()
|
|
172
|
+
})
|
|
160
173
|
|
|
161
|
-
|
|
162
|
-
return nil
|
|
174
|
+
return err
|
|
163
175
|
}
|
|
164
176
|
|
|
165
177
|
// WriteCancel writes a call cancel packet.
|
|
@@ -171,7 +183,7 @@ func (c *commonRPC) WriteCancel() error {
|
|
|
171
183
|
}
|
|
172
184
|
|
|
173
185
|
// closeLocked releases resources held by the RPC.
|
|
174
|
-
func (c *commonRPC) closeLocked() {
|
|
186
|
+
func (c *commonRPC) closeLocked(broadcast func()) {
|
|
175
187
|
c.dataClosed = true
|
|
176
188
|
if c.remoteErr == nil {
|
|
177
189
|
c.remoteErr = context.Canceled
|
|
@@ -179,6 +191,6 @@ func (c *commonRPC) closeLocked() {
|
|
|
179
191
|
if c.writer != nil {
|
|
180
192
|
_ = c.writer.Close()
|
|
181
193
|
}
|
|
182
|
-
|
|
194
|
+
broadcast()
|
|
183
195
|
c.ctxCancel()
|
|
184
196
|
}
|
package/srpc/server-rpc.go
CHANGED
|
@@ -57,27 +57,33 @@ func (r *ServerRPC) HandlePacket(msg *Packet) error {
|
|
|
57
57
|
|
|
58
58
|
// HandleCallStart handles the call start packet.
|
|
59
59
|
func (r *ServerRPC) HandleCallStart(pkt *CallStart) error {
|
|
60
|
-
|
|
61
|
-
defer r.mtx.Unlock()
|
|
62
|
-
// process start: method and service
|
|
63
|
-
if r.method != "" || r.service != "" {
|
|
64
|
-
return errors.New("call start must be sent only once")
|
|
65
|
-
}
|
|
66
|
-
if r.dataClosed {
|
|
67
|
-
return ErrCompleted
|
|
68
|
-
}
|
|
69
|
-
service, method := pkt.GetRpcService(), pkt.GetRpcMethod()
|
|
70
|
-
r.service, r.method = service, method
|
|
60
|
+
var err error
|
|
71
61
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
r.
|
|
75
|
-
|
|
62
|
+
r.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
|
|
63
|
+
// process start: method and service
|
|
64
|
+
if r.method != "" || r.service != "" {
|
|
65
|
+
err = errors.New("call start must be sent only once")
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
if r.dataClosed {
|
|
69
|
+
err = ErrCompleted
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
service, method := pkt.GetRpcService(), pkt.GetRpcMethod()
|
|
74
|
+
r.service, r.method = service, method
|
|
75
|
+
|
|
76
|
+
// process first data packet, if included
|
|
77
|
+
if data := pkt.GetData(); len(data) != 0 || pkt.GetDataIsZero() {
|
|
78
|
+
r.dataQueue = append(r.dataQueue, data)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// invoke the rpc
|
|
82
|
+
broadcast()
|
|
83
|
+
go r.invokeRPC(service, method)
|
|
84
|
+
})
|
|
76
85
|
|
|
77
|
-
|
|
78
|
-
r.bcast.Broadcast()
|
|
79
|
-
go r.invokeRPC(service, method)
|
|
80
|
-
return nil
|
|
86
|
+
return err
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
// invokeRPC invokes the RPC after CallStart is received.
|