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.
@@ -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 {
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starpc",
3
- "version": "0.33.0",
3
+ "version": "0.33.3",
4
4
  "description": "Streaming protobuf RPC service protocol over any two-way channel.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -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
- if writeFirstMsg {
41
- firstMsgEmpty = len(firstMsg) == 0
42
- }
43
- pkt := NewCallStartPacket(r.service, r.method, firstMsg, firstMsgEmpty)
44
- if err := writer.WritePacket(pkt); err != nil {
45
- r.ctxCancel()
46
- _ = writer.Close()
47
- return err
48
- }
49
- return nil
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.mtx.Lock()
64
- defer r.mtx.Unlock()
65
- defer r.bcast.Broadcast()
66
- if closeErr != nil && r.remoteErr == nil {
67
- r.remoteErr = closeErr
68
- }
69
- r.dataClosed = true
70
- r.ctxCancel()
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
- r.mtx.Lock()
106
- r.closeLocked()
107
- r.bcast.Broadcast()
108
- r.mtx.Unlock()
110
+
111
+ r.bcast.HoldLock(func(broadcast func(), getWaitCh func() <-chan struct{}) {
112
+ r.closeLocked(broadcast)
113
+ broadcast()
114
+ })
109
115
  }
@@ -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
- // mtx guards below fields
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
- c.mtx.Lock()
52
- if c.dataClosed {
53
- err := c.remoteErr
54
- c.mtx.Unlock()
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
- waiter := c.bcast.GetWaitCh()
58
- c.mtx.Unlock()
59
+
59
60
  select {
60
61
  case <-ctx.Done():
61
62
  return context.Canceled
62
- case <-waiter:
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
- c.mtx.Lock()
76
- waiter := c.bcast.GetWaitCh()
77
- if ctxDone && !c.dataClosed {
78
- // context must have been canceled locally
79
- c.closeLocked()
80
- err = context.Canceled
81
- c.mtx.Unlock()
82
- return nil, err
83
- }
84
- if len(c.dataQueue) != 0 {
85
- msg = c.dataQueue[0]
86
- c.dataQueue[0] = nil
87
- c.dataQueue = c.dataQueue[1:]
88
- c.mtx.Unlock()
89
- return msg, nil
90
- }
91
- if c.dataClosed || c.remoteErr != nil {
92
- err = c.remoteErr
93
- if err == nil {
94
- err = io.EOF
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
- c.mtx.Unlock()
100
+ })
101
+
102
+ if err != nil {
97
103
  return nil, err
98
104
  }
99
- c.mtx.Unlock()
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 <-waiter:
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.mtx.Lock()
120
- defer c.mtx.Unlock()
121
- if closeErr != nil && c.remoteErr == nil {
122
- c.remoteErr = closeErr
123
- }
124
- c.dataClosed = true
125
- c.ctxCancel()
126
- if c.writer != nil {
127
- _ = c.writer.Close()
128
- }
129
- c.bcast.Broadcast()
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
- c.mtx.Lock()
141
- defer c.mtx.Unlock()
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
- if c.dataClosed {
144
- return ErrCompleted
145
- }
157
+ if data := pkt.GetData(); len(data) != 0 || pkt.GetDataIsZero() {
158
+ c.dataQueue = append(c.dataQueue, data)
159
+ }
146
160
 
147
- if data := pkt.GetData(); len(data) != 0 || pkt.GetDataIsZero() {
148
- c.dataQueue = append(c.dataQueue, data)
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
- complete := pkt.GetComplete()
152
- if err := pkt.GetError(); len(err) != 0 {
153
- complete = true
154
- c.remoteErr = errors.New(err)
155
- }
167
+ if complete {
168
+ c.dataClosed = true
169
+ }
156
170
 
157
- if complete {
158
- c.dataClosed = true
159
- }
171
+ broadcast()
172
+ })
160
173
 
161
- c.bcast.Broadcast()
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
- c.bcast.Broadcast()
194
+ broadcast()
183
195
  c.ctxCancel()
184
196
  }
@@ -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
- r.mtx.Lock()
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
- // process first data packet, if included
73
- if data := pkt.GetData(); len(data) != 0 || pkt.GetDataIsZero() {
74
- r.dataQueue = append(r.dataQueue, data)
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
- // invoke the rpc
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.