starpc 0.41.1 → 0.41.2
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/package.json +1 -1
- package/srpc/client-invoker.go +87 -0
package/package.json
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
package srpc
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"io"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
// ClientInvoker wraps a Client to implement the Invoker interface.
|
|
8
|
+
// It proxies incoming RPC calls to the remote via the client.
|
|
9
|
+
type ClientInvoker struct {
|
|
10
|
+
// client is the client to proxy calls to
|
|
11
|
+
client Client
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// NewClientInvoker creates a new ClientInvoker.
|
|
15
|
+
func NewClientInvoker(client Client) *ClientInvoker {
|
|
16
|
+
return &ClientInvoker{client: client}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// InvokeMethod invokes the method by proxying to the remote via the client.
|
|
20
|
+
// Returns false, nil if the client is nil.
|
|
21
|
+
func (c *ClientInvoker) InvokeMethod(serviceID, methodID string, strm Stream) (bool, error) {
|
|
22
|
+
if c.client == nil {
|
|
23
|
+
return false, nil
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ctx := strm.Context()
|
|
27
|
+
|
|
28
|
+
// Open a stream to the remote
|
|
29
|
+
remoteStrm, err := c.client.NewStream(ctx, serviceID, methodID, nil)
|
|
30
|
+
if err != nil {
|
|
31
|
+
return true, err
|
|
32
|
+
}
|
|
33
|
+
defer remoteStrm.Close()
|
|
34
|
+
|
|
35
|
+
// Proxy data between the streams
|
|
36
|
+
errCh := make(chan error, 2)
|
|
37
|
+
go proxyStreamTo(strm, remoteStrm, errCh)
|
|
38
|
+
go proxyStreamTo(remoteStrm, strm, errCh)
|
|
39
|
+
|
|
40
|
+
// Wait for both directions to complete
|
|
41
|
+
var outErr error
|
|
42
|
+
for range 2 {
|
|
43
|
+
if err := <-errCh; err != nil && outErr == nil && err != io.EOF {
|
|
44
|
+
outErr = err
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true, outErr
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// proxyStreamTo copies messages from src to dst.
|
|
51
|
+
func proxyStreamTo(src, dst Stream, errCh chan error) {
|
|
52
|
+
rerr := func() error {
|
|
53
|
+
pkt := NewRawMessage(nil, true)
|
|
54
|
+
for {
|
|
55
|
+
err := src.MsgRecv(pkt)
|
|
56
|
+
if err != nil {
|
|
57
|
+
return err
|
|
58
|
+
}
|
|
59
|
+
// Forward all messages including empty ones (valid for empty proto messages)
|
|
60
|
+
err = dst.MsgSend(pkt)
|
|
61
|
+
pkt.Clear()
|
|
62
|
+
if err != nil {
|
|
63
|
+
return err
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}()
|
|
67
|
+
|
|
68
|
+
srcErr := src.Close()
|
|
69
|
+
if rerr == nil && srcErr != nil {
|
|
70
|
+
rerr = srcErr
|
|
71
|
+
}
|
|
72
|
+
if rerr != nil {
|
|
73
|
+
if errCh != nil {
|
|
74
|
+
errCh <- rerr
|
|
75
|
+
}
|
|
76
|
+
_ = dst.Close()
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
rerr = dst.CloseSend()
|
|
81
|
+
if errCh != nil {
|
|
82
|
+
errCh <- rerr
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// _ is a type assertion
|
|
87
|
+
var _ Invoker = (*ClientInvoker)(nil)
|