starpc 0.15.3 → 0.16.0
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/Makefile +2 -1
- package/dist/e2e/mock/mock.pb.d.ts +3 -3
- package/dist/e2e/mock/mock.pb.js +2 -2
- package/dist/echo/client-test.d.ts +1 -0
- package/dist/echo/client-test.js +25 -1
- package/dist/echo/echo.pb.d.ts +14 -14
- package/dist/echo/echo.pb.js +10 -10
- package/dist/integration/integration.js +10 -4
- package/dist/rpcstream/rpcstream.js +2 -4
- package/dist/srpc/client.d.ts +4 -4
- package/dist/srpc/client.js +16 -9
- package/dist/srpc/common-rpc.js +4 -3
- package/dist/srpc/errors.d.ts +2 -0
- package/dist/srpc/errors.js +10 -0
- package/dist/srpc/index.d.ts +1 -0
- package/dist/srpc/index.js +1 -0
- package/dist/srpc/server-rpc.js +6 -3
- package/dist/srpc/ts-proto-rpc.d.ts +4 -4
- package/e2e/mock/mock.pb.ts +10 -4
- package/e2e/mock/mock_srpc.pb.go +1 -1
- package/echo/client-test.ts +29 -1
- package/echo/echo.pb.ts +52 -19
- package/echo/echo_srpc.pb.go +1 -1
- package/go.mod +9 -9
- package/go.sum +19 -19
- package/integration/integration.ts +16 -4
- package/package.json +13 -13
- package/srpc/client.ts +21 -9
- package/srpc/common-rpc.ts +4 -3
- package/srpc/errors.ts +11 -0
- package/srpc/index.ts +1 -0
- package/srpc/server-rpc.ts +6 -4
- package/srpc/ts-proto-rpc.ts +8 -4
package/Makefile
CHANGED
|
@@ -110,8 +110,9 @@ gents: $(PROTOWRAP) node_modules
|
|
|
110
110
|
--ts_proto_opt=forceLong=long \
|
|
111
111
|
--ts_proto_opt=oneof=unions \
|
|
112
112
|
--ts_proto_opt=outputServices=default,outputServices=generic-definitions \
|
|
113
|
-
--ts_proto_opt=
|
|
113
|
+
--ts_proto_opt=useAbortSignal=true \
|
|
114
114
|
--ts_proto_opt=useAsyncIterable=true \
|
|
115
|
+
--ts_proto_opt=useDate=true \
|
|
115
116
|
--proto_path $$(pwd)/vendor \
|
|
116
117
|
--print_structure \
|
|
117
118
|
--only_specified_files \
|
|
@@ -21,7 +21,7 @@ export declare const MockMsg: {
|
|
|
21
21
|
/** Mock service mocks some RPCs for the e2e tests. */
|
|
22
22
|
export interface Mock {
|
|
23
23
|
/** MockRequest runs a mock unary request. */
|
|
24
|
-
MockRequest(request: MockMsg): Promise<MockMsg>;
|
|
24
|
+
MockRequest(request: MockMsg, abortSignal?: AbortSignal): Promise<MockMsg>;
|
|
25
25
|
}
|
|
26
26
|
export declare class MockClientImpl implements Mock {
|
|
27
27
|
private readonly rpc;
|
|
@@ -29,7 +29,7 @@ export declare class MockClientImpl implements Mock {
|
|
|
29
29
|
constructor(rpc: Rpc, opts?: {
|
|
30
30
|
service?: string;
|
|
31
31
|
});
|
|
32
|
-
MockRequest(request: MockMsg): Promise<MockMsg>;
|
|
32
|
+
MockRequest(request: MockMsg, abortSignal?: AbortSignal): Promise<MockMsg>;
|
|
33
33
|
}
|
|
34
34
|
/** Mock service mocks some RPCs for the e2e tests. */
|
|
35
35
|
export type MockDefinition = typeof MockDefinition;
|
|
@@ -73,7 +73,7 @@ export declare const MockDefinition: {
|
|
|
73
73
|
};
|
|
74
74
|
};
|
|
75
75
|
interface Rpc {
|
|
76
|
-
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
76
|
+
request(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
77
77
|
}
|
|
78
78
|
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
79
79
|
export type DeepPartial<T> = T extends Builtin ? T : T extends Long ? string | number | Long : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {
|
package/dist/e2e/mock/mock.pb.js
CHANGED
|
@@ -77,9 +77,9 @@ export class MockClientImpl {
|
|
|
77
77
|
this.rpc = rpc;
|
|
78
78
|
this.MockRequest = this.MockRequest.bind(this);
|
|
79
79
|
}
|
|
80
|
-
MockRequest(request) {
|
|
80
|
+
MockRequest(request, abortSignal) {
|
|
81
81
|
const data = MockMsg.encode(request).finish();
|
|
82
|
-
const promise = this.rpc.request(this.service, 'MockRequest', data);
|
|
82
|
+
const promise = this.rpc.request(this.service, 'MockRequest', data, abortSignal || undefined);
|
|
83
83
|
return promise.then((data) => MockMsg.decode(new _m0.Reader(data)));
|
|
84
84
|
}
|
|
85
85
|
}
|
package/dist/echo/client-test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Client } from '../srpc/index.js';
|
|
1
|
+
import { Client, ERR_RPC_ABORT } from '../srpc/index.js';
|
|
2
2
|
import { EchoerClientImpl } from './echo.pb.js';
|
|
3
3
|
import { pushable } from 'it-pushable';
|
|
4
4
|
import { buildRpcStreamOpenStream } from '../rpcstream/rpcstream.js';
|
|
@@ -24,6 +24,30 @@ export async function runClientTest(client) {
|
|
|
24
24
|
console.log('server: output', msg.body);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
// runAbortControllerTest tests aborting a RPC call.
|
|
28
|
+
export async function runAbortControllerTest(client) {
|
|
29
|
+
const demoServiceClient = new EchoerClientImpl(client);
|
|
30
|
+
console.log('Testing EchoClientStream with AbortController...');
|
|
31
|
+
let errorReturned = false;
|
|
32
|
+
const clientAbort = new AbortController();
|
|
33
|
+
const clientNoopStream = pushable({ objectMode: true });
|
|
34
|
+
new Promise((resolve) => setTimeout(resolve, 1000)).then(() => {
|
|
35
|
+
clientAbort.abort();
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
await demoServiceClient.EchoClientStream(clientNoopStream, clientAbort.signal);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
const errMsg = err.message;
|
|
42
|
+
errorReturned = true;
|
|
43
|
+
if (errMsg !== ERR_RPC_ABORT) {
|
|
44
|
+
throw new Error('unexpected error: ' + errMsg);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!errorReturned) {
|
|
48
|
+
throw new Error('expected aborted rpc to throw error');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
27
51
|
// runRpcStreamTest tests a RPCStream.
|
|
28
52
|
export async function runRpcStreamTest(client) {
|
|
29
53
|
console.log('Calling RpcStream to open a RPC stream client...');
|
package/dist/echo/echo.pb.d.ts
CHANGED
|
@@ -22,15 +22,15 @@ export declare const EchoMsg: {
|
|
|
22
22
|
/** Echoer service returns the given message. */
|
|
23
23
|
export interface Echoer {
|
|
24
24
|
/** Echo returns the given message. */
|
|
25
|
-
Echo(request: EchoMsg): Promise<EchoMsg>;
|
|
25
|
+
Echo(request: EchoMsg, abortSignal?: AbortSignal): Promise<EchoMsg>;
|
|
26
26
|
/** EchoServerStream is an example of a server -> client one-way stream. */
|
|
27
|
-
EchoServerStream(request: EchoMsg): AsyncIterable<EchoMsg>;
|
|
27
|
+
EchoServerStream(request: EchoMsg, abortSignal?: AbortSignal): AsyncIterable<EchoMsg>;
|
|
28
28
|
/** EchoClientStream is an example of client->server one-way stream. */
|
|
29
|
-
EchoClientStream(request: AsyncIterable<EchoMsg
|
|
29
|
+
EchoClientStream(request: AsyncIterable<EchoMsg>, abortSignal?: AbortSignal): Promise<EchoMsg>;
|
|
30
30
|
/** EchoBidiStream is an example of a two-way stream. */
|
|
31
|
-
EchoBidiStream(request: AsyncIterable<EchoMsg
|
|
31
|
+
EchoBidiStream(request: AsyncIterable<EchoMsg>, abortSignal?: AbortSignal): AsyncIterable<EchoMsg>;
|
|
32
32
|
/** RpcStream opens a nested rpc call stream. */
|
|
33
|
-
RpcStream(request: AsyncIterable<RpcStreamPacket
|
|
33
|
+
RpcStream(request: AsyncIterable<RpcStreamPacket>, abortSignal?: AbortSignal): AsyncIterable<RpcStreamPacket>;
|
|
34
34
|
}
|
|
35
35
|
export declare class EchoerClientImpl implements Echoer {
|
|
36
36
|
private readonly rpc;
|
|
@@ -38,11 +38,11 @@ export declare class EchoerClientImpl implements Echoer {
|
|
|
38
38
|
constructor(rpc: Rpc, opts?: {
|
|
39
39
|
service?: string;
|
|
40
40
|
});
|
|
41
|
-
Echo(request: EchoMsg): Promise<EchoMsg>;
|
|
42
|
-
EchoServerStream(request: EchoMsg): AsyncIterable<EchoMsg>;
|
|
43
|
-
EchoClientStream(request: AsyncIterable<EchoMsg
|
|
44
|
-
EchoBidiStream(request: AsyncIterable<EchoMsg
|
|
45
|
-
RpcStream(request: AsyncIterable<RpcStreamPacket
|
|
41
|
+
Echo(request: EchoMsg, abortSignal?: AbortSignal): Promise<EchoMsg>;
|
|
42
|
+
EchoServerStream(request: EchoMsg, abortSignal?: AbortSignal): AsyncIterable<EchoMsg>;
|
|
43
|
+
EchoClientStream(request: AsyncIterable<EchoMsg>, abortSignal?: AbortSignal): Promise<EchoMsg>;
|
|
44
|
+
EchoBidiStream(request: AsyncIterable<EchoMsg>, abortSignal?: AbortSignal): AsyncIterable<EchoMsg>;
|
|
45
|
+
RpcStream(request: AsyncIterable<RpcStreamPacket>, abortSignal?: AbortSignal): AsyncIterable<RpcStreamPacket>;
|
|
46
46
|
}
|
|
47
47
|
/** Echoer service returns the given message. */
|
|
48
48
|
export type EchoerDefinition = typeof EchoerDefinition;
|
|
@@ -316,10 +316,10 @@ export declare const EchoerDefinition: {
|
|
|
316
316
|
};
|
|
317
317
|
};
|
|
318
318
|
interface Rpc {
|
|
319
|
-
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
320
|
-
clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array
|
|
321
|
-
serverStreamingRequest(service: string, method: string, data: Uint8Array): AsyncIterable<Uint8Array>;
|
|
322
|
-
bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array
|
|
319
|
+
request(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
320
|
+
clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
321
|
+
serverStreamingRequest(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
322
|
+
bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>, abortSignal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
323
323
|
}
|
|
324
324
|
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
325
325
|
export type DeepPartial<T> = T extends Builtin ? T : T extends Long ? string | number | Long : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {
|
package/dist/echo/echo.pb.js
CHANGED
|
@@ -82,29 +82,29 @@ export class EchoerClientImpl {
|
|
|
82
82
|
this.EchoBidiStream = this.EchoBidiStream.bind(this);
|
|
83
83
|
this.RpcStream = this.RpcStream.bind(this);
|
|
84
84
|
}
|
|
85
|
-
Echo(request) {
|
|
85
|
+
Echo(request, abortSignal) {
|
|
86
86
|
const data = EchoMsg.encode(request).finish();
|
|
87
|
-
const promise = this.rpc.request(this.service, 'Echo', data);
|
|
87
|
+
const promise = this.rpc.request(this.service, 'Echo', data, abortSignal || undefined);
|
|
88
88
|
return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)));
|
|
89
89
|
}
|
|
90
|
-
EchoServerStream(request) {
|
|
90
|
+
EchoServerStream(request, abortSignal) {
|
|
91
91
|
const data = EchoMsg.encode(request).finish();
|
|
92
|
-
const result = this.rpc.serverStreamingRequest(this.service, 'EchoServerStream', data);
|
|
92
|
+
const result = this.rpc.serverStreamingRequest(this.service, 'EchoServerStream', data, abortSignal || undefined);
|
|
93
93
|
return EchoMsg.decodeTransform(result);
|
|
94
94
|
}
|
|
95
|
-
EchoClientStream(request) {
|
|
95
|
+
EchoClientStream(request, abortSignal) {
|
|
96
96
|
const data = EchoMsg.encodeTransform(request);
|
|
97
|
-
const promise = this.rpc.clientStreamingRequest(this.service, 'EchoClientStream', data);
|
|
97
|
+
const promise = this.rpc.clientStreamingRequest(this.service, 'EchoClientStream', data, abortSignal || undefined);
|
|
98
98
|
return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)));
|
|
99
99
|
}
|
|
100
|
-
EchoBidiStream(request) {
|
|
100
|
+
EchoBidiStream(request, abortSignal) {
|
|
101
101
|
const data = EchoMsg.encodeTransform(request);
|
|
102
|
-
const result = this.rpc.bidirectionalStreamingRequest(this.service, 'EchoBidiStream', data);
|
|
102
|
+
const result = this.rpc.bidirectionalStreamingRequest(this.service, 'EchoBidiStream', data, abortSignal || undefined);
|
|
103
103
|
return EchoMsg.decodeTransform(result);
|
|
104
104
|
}
|
|
105
|
-
RpcStream(request) {
|
|
105
|
+
RpcStream(request, abortSignal) {
|
|
106
106
|
const data = RpcStreamPacket.encodeTransform(request);
|
|
107
|
-
const result = this.rpc.bidirectionalStreamingRequest(this.service, 'RpcStream', data);
|
|
107
|
+
const result = this.rpc.bidirectionalStreamingRequest(this.service, 'RpcStream', data, abortSignal || undefined);
|
|
108
108
|
return RpcStreamPacket.decodeTransform(result);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WebSocketConn } from '../srpc/websocket.js';
|
|
2
|
-
import { runClientTest, runRpcStreamTest } from '../echo/client-test.js';
|
|
2
|
+
import { runClientTest, runRpcStreamTest, runAbortControllerTest, } from '../echo/client-test.js';
|
|
3
3
|
import WebSocket from 'isomorphic-ws';
|
|
4
4
|
async function runRPC() {
|
|
5
5
|
const addr = 'ws://localhost:5000/demo';
|
|
@@ -7,16 +7,22 @@ async function runRPC() {
|
|
|
7
7
|
const ws = new WebSocket(addr);
|
|
8
8
|
const channel = new WebSocketConn(ws, 'outbound');
|
|
9
9
|
const client = channel.buildClient();
|
|
10
|
-
console.log('Running client test via WebSocket..');
|
|
11
|
-
await runClientTest(client);
|
|
12
10
|
console.log('Running RpcStream test via WebSocket..');
|
|
13
11
|
await runRpcStreamTest(client);
|
|
12
|
+
console.log('Running client test via WebSocket..');
|
|
13
|
+
await runClientTest(client);
|
|
14
|
+
console.log('Running abort controller test via WebSocket..');
|
|
15
|
+
await runAbortControllerTest(client);
|
|
14
16
|
}
|
|
17
|
+
process.on('unhandledRejection', (ev) => {
|
|
18
|
+
console.error('Unhandled rejection', ev);
|
|
19
|
+
throw ev;
|
|
20
|
+
});
|
|
15
21
|
runRPC()
|
|
16
22
|
.then(() => {
|
|
17
23
|
process.exit(0);
|
|
18
24
|
})
|
|
19
25
|
.catch((err) => {
|
|
20
|
-
console.error(err);
|
|
26
|
+
console.error('runRPC threw error', err);
|
|
21
27
|
process.exit(1);
|
|
22
28
|
});
|
|
@@ -81,11 +81,9 @@ export async function* handleRpcStream(packetStream, getter) {
|
|
|
81
81
|
}
|
|
82
82
|
// build the outgoing packet sink & the packet source
|
|
83
83
|
const packetSink = pushable({ objectMode: true });
|
|
84
|
-
//
|
|
84
|
+
// start the handler
|
|
85
85
|
const rpcStream = new RpcStream(packetSink, packetStream);
|
|
86
|
-
|
|
87
|
-
handler(rpcStream);
|
|
88
|
-
}, 1);
|
|
86
|
+
handler(rpcStream);
|
|
89
87
|
// process packets
|
|
90
88
|
for await (const packet of packetSink) {
|
|
91
89
|
yield* [packet];
|
package/dist/srpc/client.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ export declare class Client implements TsProtoRpc {
|
|
|
4
4
|
private openStreamCtr;
|
|
5
5
|
constructor(openStreamFn?: OpenStreamFunc);
|
|
6
6
|
setOpenStreamFn(openStreamFn?: OpenStreamFunc): void;
|
|
7
|
-
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
8
|
-
clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array
|
|
9
|
-
serverStreamingRequest(service: string, method: string, data: Uint8Array): AsyncIterable<Uint8Array>;
|
|
10
|
-
bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array
|
|
7
|
+
request(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
8
|
+
clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
9
|
+
serverStreamingRequest(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
10
|
+
bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>, abortSignal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
11
11
|
private startRpc;
|
|
12
12
|
}
|
package/dist/srpc/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { pipe } from 'it-pipe';
|
|
2
2
|
import { pushable } from 'it-pushable';
|
|
3
|
+
import { ERR_RPC_ABORT } from './errors.js';
|
|
3
4
|
import { ClientRPC } from './client-rpc.js';
|
|
4
5
|
import { writeToPushable } from './pushable.js';
|
|
5
6
|
import { decodePacketSource, encodePacketSource, parseLengthPrefixTransform, prependLengthPrefixTransform, } from './packet.js';
|
|
@@ -15,8 +16,8 @@ export class Client {
|
|
|
15
16
|
this.openStreamCtr.set(openStreamFn || undefined);
|
|
16
17
|
}
|
|
17
18
|
// request starts a non-streaming request.
|
|
18
|
-
async request(service, method, data) {
|
|
19
|
-
const call = await this.startRpc(service, method, data);
|
|
19
|
+
async request(service, method, data, abortSignal) {
|
|
20
|
+
const call = await this.startRpc(service, method, data, abortSignal);
|
|
20
21
|
for await (const data of call.rpcDataSource) {
|
|
21
22
|
call.close();
|
|
22
23
|
return data;
|
|
@@ -26,8 +27,8 @@ export class Client {
|
|
|
26
27
|
throw err;
|
|
27
28
|
}
|
|
28
29
|
// clientStreamingRequest starts a client side streaming request.
|
|
29
|
-
async clientStreamingRequest(service, method, data) {
|
|
30
|
-
const call = await this.startRpc(service, method, null);
|
|
30
|
+
async clientStreamingRequest(service, method, data, abortSignal) {
|
|
31
|
+
const call = await this.startRpc(service, method, null, abortSignal);
|
|
31
32
|
call.writeCallDataFromSource(data);
|
|
32
33
|
for await (const data of call.rpcDataSource) {
|
|
33
34
|
call.close();
|
|
@@ -38,9 +39,9 @@ export class Client {
|
|
|
38
39
|
throw err;
|
|
39
40
|
}
|
|
40
41
|
// serverStreamingRequest starts a server-side streaming request.
|
|
41
|
-
serverStreamingRequest(service, method, data) {
|
|
42
|
+
serverStreamingRequest(service, method, data, abortSignal) {
|
|
42
43
|
const serverData = pushable({ objectMode: true });
|
|
43
|
-
this.startRpc(service, method, data)
|
|
44
|
+
this.startRpc(service, method, data, abortSignal)
|
|
44
45
|
.then(async (call) => {
|
|
45
46
|
return writeToPushable(call.rpcDataSource, serverData);
|
|
46
47
|
})
|
|
@@ -48,9 +49,9 @@ export class Client {
|
|
|
48
49
|
return serverData;
|
|
49
50
|
}
|
|
50
51
|
// bidirectionalStreamingRequest starts a two-way streaming request.
|
|
51
|
-
bidirectionalStreamingRequest(service, method, data) {
|
|
52
|
+
bidirectionalStreamingRequest(service, method, data, abortSignal) {
|
|
52
53
|
const serverData = pushable({ objectMode: true });
|
|
53
|
-
this.startRpc(service, method, null)
|
|
54
|
+
this.startRpc(service, method, null, abortSignal)
|
|
54
55
|
.then(async (call) => {
|
|
55
56
|
call.writeCallDataFromSource(data);
|
|
56
57
|
try {
|
|
@@ -69,10 +70,16 @@ export class Client {
|
|
|
69
70
|
// startRpc is a common utility function to begin a rpc call.
|
|
70
71
|
// throws any error starting the rpc call
|
|
71
72
|
// if data == null and data.length == 0, sends a separate data packet.
|
|
72
|
-
async startRpc(rpcService, rpcMethod, data) {
|
|
73
|
+
async startRpc(rpcService, rpcMethod, data, abortSignal) {
|
|
74
|
+
if (abortSignal?.aborted) {
|
|
75
|
+
throw new Error(ERR_RPC_ABORT);
|
|
76
|
+
}
|
|
73
77
|
const openStreamFn = await this.openStreamCtr.wait();
|
|
74
78
|
const conn = await openStreamFn();
|
|
75
79
|
const call = new ClientRPC(rpcService, rpcMethod);
|
|
80
|
+
abortSignal?.addEventListener('abort', () => {
|
|
81
|
+
call.close(new Error(ERR_RPC_ABORT));
|
|
82
|
+
});
|
|
76
83
|
pipe(conn, parseLengthPrefixTransform(), combineUint8ArrayListTransform(), decodePacketSource, call, encodePacketSource, prependLengthPrefixTransform(), conn);
|
|
77
84
|
await call.writeCallStart(data || undefined);
|
|
78
85
|
return call;
|
package/dist/srpc/common-rpc.js
CHANGED
|
@@ -39,9 +39,9 @@ export class CommonRPC {
|
|
|
39
39
|
async writeCallDataFromSource(dataSource) {
|
|
40
40
|
try {
|
|
41
41
|
for await (const data of dataSource) {
|
|
42
|
-
this.writeCallData(data);
|
|
42
|
+
await this.writeCallData(data);
|
|
43
43
|
}
|
|
44
|
-
this.writeCallData(undefined, true);
|
|
44
|
+
await this.writeCallData(undefined, true);
|
|
45
45
|
}
|
|
46
46
|
catch (err) {
|
|
47
47
|
this.close(err);
|
|
@@ -117,7 +117,8 @@ export class CommonRPC {
|
|
|
117
117
|
}
|
|
118
118
|
finally {
|
|
119
119
|
this._rpcDataSource.end(err);
|
|
120
|
-
|
|
120
|
+
// note: don't pass error to _source here.
|
|
121
|
+
this._source.end();
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
// _createSink returns a value for the sink field.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// ERR_RPC_ABORT is returned if the RPC was aborted.
|
|
2
|
+
export const ERR_RPC_ABORT = 'ERR_RPC_ABORT';
|
|
3
|
+
// isAbortError checks if the error object is ERR_RPC_ABORT.
|
|
4
|
+
export function isAbortError(err) {
|
|
5
|
+
if (typeof err !== 'object') {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const message = err.message;
|
|
9
|
+
return message === ERR_RPC_ABORT;
|
|
10
|
+
}
|
package/dist/srpc/index.d.ts
CHANGED
package/dist/srpc/index.js
CHANGED
package/dist/srpc/server-rpc.js
CHANGED
|
@@ -33,11 +33,14 @@ export class ServerRPC extends CommonRPC {
|
|
|
33
33
|
return super.handleCallData(packet);
|
|
34
34
|
}
|
|
35
35
|
// invokeRPC starts invoking the RPC handler.
|
|
36
|
-
invokeRPC(invokeFn) {
|
|
36
|
+
async invokeRPC(invokeFn) {
|
|
37
37
|
const dataSink = this._createDataSink();
|
|
38
|
-
|
|
38
|
+
try {
|
|
39
|
+
await invokeFn(this.rpcDataSource, dataSink);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
39
42
|
this.close(err);
|
|
40
|
-
}
|
|
43
|
+
}
|
|
41
44
|
}
|
|
42
45
|
// _createDataSink creates a sink for outgoing data packets.
|
|
43
46
|
_createDataSink() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface TsProtoRpc {
|
|
2
|
-
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
3
|
-
clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array
|
|
4
|
-
serverStreamingRequest(service: string, method: string, data: Uint8Array): AsyncIterable<Uint8Array>;
|
|
5
|
-
bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array
|
|
2
|
+
request(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
3
|
+
clientStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>, abortSignal?: AbortSignal): Promise<Uint8Array>;
|
|
4
|
+
serverStreamingRequest(service: string, method: string, data: Uint8Array, abortSignal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
5
|
+
bidirectionalStreamingRequest(service: string, method: string, data: AsyncIterable<Uint8Array>, abortSignal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
6
6
|
}
|
package/e2e/mock/mock.pb.ts
CHANGED
|
@@ -96,7 +96,7 @@ export const MockMsg = {
|
|
|
96
96
|
/** Mock service mocks some RPCs for the e2e tests. */
|
|
97
97
|
export interface Mock {
|
|
98
98
|
/** MockRequest runs a mock unary request. */
|
|
99
|
-
MockRequest(request: MockMsg): Promise<MockMsg>
|
|
99
|
+
MockRequest(request: MockMsg, abortSignal?: AbortSignal): Promise<MockMsg>
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export class MockClientImpl implements Mock {
|
|
@@ -107,9 +107,14 @@ export class MockClientImpl implements Mock {
|
|
|
107
107
|
this.rpc = rpc
|
|
108
108
|
this.MockRequest = this.MockRequest.bind(this)
|
|
109
109
|
}
|
|
110
|
-
MockRequest(request: MockMsg): Promise<MockMsg> {
|
|
110
|
+
MockRequest(request: MockMsg, abortSignal?: AbortSignal): Promise<MockMsg> {
|
|
111
111
|
const data = MockMsg.encode(request).finish()
|
|
112
|
-
const promise = this.rpc.request(
|
|
112
|
+
const promise = this.rpc.request(
|
|
113
|
+
this.service,
|
|
114
|
+
'MockRequest',
|
|
115
|
+
data,
|
|
116
|
+
abortSignal || undefined
|
|
117
|
+
)
|
|
113
118
|
return promise.then((data) => MockMsg.decode(new _m0.Reader(data)))
|
|
114
119
|
}
|
|
115
120
|
}
|
|
@@ -136,7 +141,8 @@ interface Rpc {
|
|
|
136
141
|
request(
|
|
137
142
|
service: string,
|
|
138
143
|
method: string,
|
|
139
|
-
data: Uint8Array
|
|
144
|
+
data: Uint8Array,
|
|
145
|
+
abortSignal?: AbortSignal
|
|
140
146
|
): Promise<Uint8Array>
|
|
141
147
|
}
|
|
142
148
|
|
package/e2e/mock/mock_srpc.pb.go
CHANGED
package/echo/client-test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Client } from '../srpc/index.js'
|
|
1
|
+
import { Client, ERR_RPC_ABORT } from '../srpc/index.js'
|
|
2
2
|
import { EchoerClientImpl, EchoMsg } from './echo.pb.js'
|
|
3
3
|
import { pushable } from 'it-pushable'
|
|
4
4
|
import { buildRpcStreamOpenStream } from '../rpcstream/rpcstream.js'
|
|
@@ -30,6 +30,34 @@ export async function runClientTest(client: Client) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// runAbortControllerTest tests aborting a RPC call.
|
|
34
|
+
export async function runAbortControllerTest(client: Client) {
|
|
35
|
+
const demoServiceClient = new EchoerClientImpl(client)
|
|
36
|
+
|
|
37
|
+
console.log('Testing EchoClientStream with AbortController...')
|
|
38
|
+
let errorReturned = false
|
|
39
|
+
const clientAbort = new AbortController()
|
|
40
|
+
const clientNoopStream = pushable<EchoMsg>({ objectMode: true })
|
|
41
|
+
new Promise((resolve) => setTimeout(resolve, 1000)).then(() => {
|
|
42
|
+
clientAbort.abort()
|
|
43
|
+
})
|
|
44
|
+
try {
|
|
45
|
+
await demoServiceClient.EchoClientStream(
|
|
46
|
+
clientNoopStream,
|
|
47
|
+
clientAbort.signal
|
|
48
|
+
)
|
|
49
|
+
} catch (err) {
|
|
50
|
+
const errMsg = (err as Error).message
|
|
51
|
+
errorReturned = true
|
|
52
|
+
if (errMsg !== ERR_RPC_ABORT) {
|
|
53
|
+
throw new Error('unexpected error: ' + errMsg)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!errorReturned) {
|
|
57
|
+
throw new Error('expected aborted rpc to throw error')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
33
61
|
// runRpcStreamTest tests a RPCStream.
|
|
34
62
|
export async function runRpcStreamTest(client: Client) {
|
|
35
63
|
console.log('Calling RpcStream to open a RPC stream client...')
|
package/echo/echo.pb.ts
CHANGED
|
@@ -97,16 +97,26 @@ export const EchoMsg = {
|
|
|
97
97
|
/** Echoer service returns the given message. */
|
|
98
98
|
export interface Echoer {
|
|
99
99
|
/** Echo returns the given message. */
|
|
100
|
-
Echo(request: EchoMsg): Promise<EchoMsg>
|
|
100
|
+
Echo(request: EchoMsg, abortSignal?: AbortSignal): Promise<EchoMsg>
|
|
101
101
|
/** EchoServerStream is an example of a server -> client one-way stream. */
|
|
102
|
-
EchoServerStream(
|
|
102
|
+
EchoServerStream(
|
|
103
|
+
request: EchoMsg,
|
|
104
|
+
abortSignal?: AbortSignal
|
|
105
|
+
): AsyncIterable<EchoMsg>
|
|
103
106
|
/** EchoClientStream is an example of client->server one-way stream. */
|
|
104
|
-
EchoClientStream(
|
|
107
|
+
EchoClientStream(
|
|
108
|
+
request: AsyncIterable<EchoMsg>,
|
|
109
|
+
abortSignal?: AbortSignal
|
|
110
|
+
): Promise<EchoMsg>
|
|
105
111
|
/** EchoBidiStream is an example of a two-way stream. */
|
|
106
|
-
EchoBidiStream(
|
|
112
|
+
EchoBidiStream(
|
|
113
|
+
request: AsyncIterable<EchoMsg>,
|
|
114
|
+
abortSignal?: AbortSignal
|
|
115
|
+
): AsyncIterable<EchoMsg>
|
|
107
116
|
/** RpcStream opens a nested rpc call stream. */
|
|
108
117
|
RpcStream(
|
|
109
|
-
request: AsyncIterable<RpcStreamPacket
|
|
118
|
+
request: AsyncIterable<RpcStreamPacket>,
|
|
119
|
+
abortSignal?: AbortSignal
|
|
110
120
|
): AsyncIterable<RpcStreamPacket>
|
|
111
121
|
}
|
|
112
122
|
|
|
@@ -122,50 +132,69 @@ export class EchoerClientImpl implements Echoer {
|
|
|
122
132
|
this.EchoBidiStream = this.EchoBidiStream.bind(this)
|
|
123
133
|
this.RpcStream = this.RpcStream.bind(this)
|
|
124
134
|
}
|
|
125
|
-
Echo(request: EchoMsg): Promise<EchoMsg> {
|
|
135
|
+
Echo(request: EchoMsg, abortSignal?: AbortSignal): Promise<EchoMsg> {
|
|
126
136
|
const data = EchoMsg.encode(request).finish()
|
|
127
|
-
const promise = this.rpc.request(
|
|
137
|
+
const promise = this.rpc.request(
|
|
138
|
+
this.service,
|
|
139
|
+
'Echo',
|
|
140
|
+
data,
|
|
141
|
+
abortSignal || undefined
|
|
142
|
+
)
|
|
128
143
|
return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)))
|
|
129
144
|
}
|
|
130
145
|
|
|
131
|
-
EchoServerStream(
|
|
146
|
+
EchoServerStream(
|
|
147
|
+
request: EchoMsg,
|
|
148
|
+
abortSignal?: AbortSignal
|
|
149
|
+
): AsyncIterable<EchoMsg> {
|
|
132
150
|
const data = EchoMsg.encode(request).finish()
|
|
133
151
|
const result = this.rpc.serverStreamingRequest(
|
|
134
152
|
this.service,
|
|
135
153
|
'EchoServerStream',
|
|
136
|
-
data
|
|
154
|
+
data,
|
|
155
|
+
abortSignal || undefined
|
|
137
156
|
)
|
|
138
157
|
return EchoMsg.decodeTransform(result)
|
|
139
158
|
}
|
|
140
159
|
|
|
141
|
-
EchoClientStream(
|
|
160
|
+
EchoClientStream(
|
|
161
|
+
request: AsyncIterable<EchoMsg>,
|
|
162
|
+
abortSignal?: AbortSignal
|
|
163
|
+
): Promise<EchoMsg> {
|
|
142
164
|
const data = EchoMsg.encodeTransform(request)
|
|
143
165
|
const promise = this.rpc.clientStreamingRequest(
|
|
144
166
|
this.service,
|
|
145
167
|
'EchoClientStream',
|
|
146
|
-
data
|
|
168
|
+
data,
|
|
169
|
+
abortSignal || undefined
|
|
147
170
|
)
|
|
148
171
|
return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)))
|
|
149
172
|
}
|
|
150
173
|
|
|
151
|
-
EchoBidiStream(
|
|
174
|
+
EchoBidiStream(
|
|
175
|
+
request: AsyncIterable<EchoMsg>,
|
|
176
|
+
abortSignal?: AbortSignal
|
|
177
|
+
): AsyncIterable<EchoMsg> {
|
|
152
178
|
const data = EchoMsg.encodeTransform(request)
|
|
153
179
|
const result = this.rpc.bidirectionalStreamingRequest(
|
|
154
180
|
this.service,
|
|
155
181
|
'EchoBidiStream',
|
|
156
|
-
data
|
|
182
|
+
data,
|
|
183
|
+
abortSignal || undefined
|
|
157
184
|
)
|
|
158
185
|
return EchoMsg.decodeTransform(result)
|
|
159
186
|
}
|
|
160
187
|
|
|
161
188
|
RpcStream(
|
|
162
|
-
request: AsyncIterable<RpcStreamPacket
|
|
189
|
+
request: AsyncIterable<RpcStreamPacket>,
|
|
190
|
+
abortSignal?: AbortSignal
|
|
163
191
|
): AsyncIterable<RpcStreamPacket> {
|
|
164
192
|
const data = RpcStreamPacket.encodeTransform(request)
|
|
165
193
|
const result = this.rpc.bidirectionalStreamingRequest(
|
|
166
194
|
this.service,
|
|
167
195
|
'RpcStream',
|
|
168
|
-
data
|
|
196
|
+
data,
|
|
197
|
+
abortSignal || undefined
|
|
169
198
|
)
|
|
170
199
|
return RpcStreamPacket.decodeTransform(result)
|
|
171
200
|
}
|
|
@@ -229,22 +258,26 @@ interface Rpc {
|
|
|
229
258
|
request(
|
|
230
259
|
service: string,
|
|
231
260
|
method: string,
|
|
232
|
-
data: Uint8Array
|
|
261
|
+
data: Uint8Array,
|
|
262
|
+
abortSignal?: AbortSignal
|
|
233
263
|
): Promise<Uint8Array>
|
|
234
264
|
clientStreamingRequest(
|
|
235
265
|
service: string,
|
|
236
266
|
method: string,
|
|
237
|
-
data: AsyncIterable<Uint8Array
|
|
267
|
+
data: AsyncIterable<Uint8Array>,
|
|
268
|
+
abortSignal?: AbortSignal
|
|
238
269
|
): Promise<Uint8Array>
|
|
239
270
|
serverStreamingRequest(
|
|
240
271
|
service: string,
|
|
241
272
|
method: string,
|
|
242
|
-
data: Uint8Array
|
|
273
|
+
data: Uint8Array,
|
|
274
|
+
abortSignal?: AbortSignal
|
|
243
275
|
): AsyncIterable<Uint8Array>
|
|
244
276
|
bidirectionalStreamingRequest(
|
|
245
277
|
service: string,
|
|
246
278
|
method: string,
|
|
247
|
-
data: AsyncIterable<Uint8Array
|
|
279
|
+
data: AsyncIterable<Uint8Array>,
|
|
280
|
+
abortSignal?: AbortSignal
|
|
248
281
|
): AsyncIterable<Uint8Array>
|
|
249
282
|
}
|
|
250
283
|
|
package/echo/echo_srpc.pb.go
CHANGED
package/go.mod
CHANGED
|
@@ -5,12 +5,12 @@ go 1.18
|
|
|
5
5
|
require (
|
|
6
6
|
github.com/pkg/errors v0.9.1
|
|
7
7
|
google.golang.org/protobuf v1.28.1
|
|
8
|
-
nhooyr.io/websocket v1.8.8-0.
|
|
8
|
+
nhooyr.io/websocket v1.8.8-0.20221213223501-14fb98eba64e
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
require (
|
|
12
|
-
github.com/aperturerobotics/util v0.0.0-
|
|
13
|
-
github.com/libp2p/go-libp2p v0.24.
|
|
12
|
+
github.com/aperturerobotics/util v0.0.0-20221205090205-f776a34d2d0d
|
|
13
|
+
github.com/libp2p/go-libp2p v0.24.1
|
|
14
14
|
github.com/libp2p/go-yamux/v4 v4.0.1-0.20220919134236-1c09f2ab3ec1
|
|
15
15
|
github.com/sirupsen/logrus v1.9.0
|
|
16
16
|
)
|
|
@@ -19,23 +19,23 @@ require (
|
|
|
19
19
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
|
20
20
|
github.com/gogo/protobuf v1.3.2 // indirect
|
|
21
21
|
github.com/ipfs/go-cid v0.3.2 // indirect
|
|
22
|
-
github.com/klauspost/compress v1.15.
|
|
23
|
-
github.com/klauspost/cpuid/v2 v2.
|
|
22
|
+
github.com/klauspost/compress v1.15.12 // indirect
|
|
23
|
+
github.com/klauspost/cpuid/v2 v2.2.1 // indirect
|
|
24
24
|
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
|
25
25
|
github.com/libp2p/go-openssl v0.1.0 // indirect
|
|
26
26
|
github.com/mattn/go-pointer v0.0.1 // indirect
|
|
27
27
|
github.com/minio/sha256-simd v1.0.0 // indirect
|
|
28
28
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
|
29
29
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
|
30
|
-
github.com/multiformats/go-base36 v0.
|
|
30
|
+
github.com/multiformats/go-base36 v0.2.0 // indirect
|
|
31
31
|
github.com/multiformats/go-multiaddr v0.8.0 // indirect
|
|
32
32
|
github.com/multiformats/go-multibase v0.1.2-0.20220823162309-7160a7347ed1 // indirect
|
|
33
33
|
github.com/multiformats/go-multicodec v0.7.1-0.20221017174837-a2baec7ca709 // indirect
|
|
34
34
|
github.com/multiformats/go-multihash v0.2.2-0.20221030163302-608669da49b6 // indirect
|
|
35
|
-
github.com/multiformats/go-varint v0.0.7
|
|
35
|
+
github.com/multiformats/go-varint v0.0.7 // indirect
|
|
36
36
|
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
|
37
37
|
github.com/spaolacci/murmur3 v1.1.1-0.20190317074736-539464a789e9 // indirect
|
|
38
|
-
golang.org/x/crypto v0.
|
|
39
|
-
golang.org/x/sys v0.
|
|
38
|
+
golang.org/x/crypto v0.3.0 // indirect
|
|
39
|
+
golang.org/x/sys v0.3.0 // indirect
|
|
40
40
|
lukechampine.com/blake3 v1.1.8-0.20220321170924-7afca5966e5e // indirect
|
|
41
41
|
)
|
package/go.sum
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
github.com/aperturerobotics/util v0.0.0-
|
|
2
|
-
github.com/aperturerobotics/util v0.0.0-
|
|
1
|
+
github.com/aperturerobotics/util v0.0.0-20221205090205-f776a34d2d0d h1:nYXEY4LHTW7a7Vf+Lt+7icxoc02wIyLCa12xPbFuIxo=
|
|
2
|
+
github.com/aperturerobotics/util v0.0.0-20221205090205-f776a34d2d0d/go.mod h1:up2AYcp62UgmFVTm7QhM4USXAKGv73gpb5dHraKmzxQ=
|
|
3
3
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
4
4
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
5
5
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
@@ -42,18 +42,18 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
|
|
|
42
42
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
|
43
43
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
44
44
|
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
|
45
|
-
github.com/klauspost/compress v1.15.
|
|
46
|
-
github.com/klauspost/compress v1.15.
|
|
45
|
+
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
|
|
46
|
+
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
|
47
47
|
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
|
48
48
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
|
49
|
-
github.com/klauspost/cpuid/v2 v2.
|
|
50
|
-
github.com/klauspost/cpuid/v2 v2.
|
|
49
|
+
github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI=
|
|
50
|
+
github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
|
51
51
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
|
52
52
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
|
53
53
|
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
|
54
54
|
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
|
55
|
-
github.com/libp2p/go-libp2p v0.24.
|
|
56
|
-
github.com/libp2p/go-libp2p v0.24.
|
|
55
|
+
github.com/libp2p/go-libp2p v0.24.1 h1:+lS4fqj7RF9egcPq9Yo3iqdRTcDMApzoBbQMhxtwOVw=
|
|
56
|
+
github.com/libp2p/go-libp2p v0.24.1/go.mod h1:5LJqbrqFsUzWrq70JHCYqjATlX4ey8Klpct3OEe8hSI=
|
|
57
57
|
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
|
|
58
58
|
github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo=
|
|
59
59
|
github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc=
|
|
@@ -73,8 +73,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
|
|
73
73
|
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
|
74
74
|
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
|
|
75
75
|
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
|
76
|
-
github.com/multiformats/go-base36 v0.
|
|
77
|
-
github.com/multiformats/go-base36 v0.
|
|
76
|
+
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
|
77
|
+
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
|
78
78
|
github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU=
|
|
79
79
|
github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs=
|
|
80
80
|
github.com/multiformats/go-multibase v0.1.2-0.20220823162309-7160a7347ed1 h1:fts9VGSGzcENj3XnQ3iz9LGMAJAqT46fUGyaUDGFuxQ=
|
|
@@ -83,8 +83,8 @@ github.com/multiformats/go-multicodec v0.7.1-0.20221017174837-a2baec7ca709 h1:Xw
|
|
|
83
83
|
github.com/multiformats/go-multicodec v0.7.1-0.20221017174837-a2baec7ca709/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw=
|
|
84
84
|
github.com/multiformats/go-multihash v0.2.2-0.20221030163302-608669da49b6 h1:qLF997Rz0X1WvdcZ2r5CUkLZ2rvdiXwG1JRSrJZEAuE=
|
|
85
85
|
github.com/multiformats/go-multihash v0.2.2-0.20221030163302-608669da49b6/go.mod h1:kaHxr8TfO1cxIR/tYxgZ7e59HraJq8arEQQR8E/YNvI=
|
|
86
|
-
github.com/multiformats/go-varint v0.0.7
|
|
87
|
-
github.com/multiformats/go-varint v0.0.7
|
|
86
|
+
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
|
87
|
+
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
|
88
88
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
89
89
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
90
90
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
@@ -99,7 +99,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|
|
99
99
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
100
100
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
101
101
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
102
|
-
github.com/stretchr/testify v1.8.
|
|
102
|
+
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
103
103
|
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
|
104
104
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
|
105
105
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
|
@@ -109,8 +109,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|
|
109
109
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
110
110
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
111
111
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
112
|
-
golang.org/x/crypto v0.
|
|
113
|
-
golang.org/x/crypto v0.
|
|
112
|
+
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
|
113
|
+
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
|
114
114
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
115
115
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
116
116
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
@@ -126,8 +126,8 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
|
|
|
126
126
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
127
127
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
128
128
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
129
|
-
golang.org/x/sys v0.
|
|
130
|
-
golang.org/x/sys v0.
|
|
129
|
+
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
|
130
|
+
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
131
131
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
132
132
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
133
133
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
@@ -152,5 +152,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|
|
152
152
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
153
153
|
lukechampine.com/blake3 v1.1.8-0.20220321170924-7afca5966e5e h1:YeQnmA0g9M+7uVBjUXNUpVQRfWrvTu4I5u+DjFudflw=
|
|
154
154
|
lukechampine.com/blake3 v1.1.8-0.20220321170924-7afca5966e5e/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
|
155
|
-
nhooyr.io/websocket v1.8.8-0.
|
|
156
|
-
nhooyr.io/websocket v1.8.8-0.
|
|
155
|
+
nhooyr.io/websocket v1.8.8-0.20221213223501-14fb98eba64e h1:Sk+k5z84Elo/gfEvX1xQR83Yhd6ETPmVDJTXUd2BxR4=
|
|
156
|
+
nhooyr.io/websocket v1.8.8-0.20221213223501-14fb98eba64e/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { WebSocketConn } from '../srpc/websocket.js'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
runClientTest,
|
|
4
|
+
runRpcStreamTest,
|
|
5
|
+
runAbortControllerTest,
|
|
6
|
+
} from '../echo/client-test.js'
|
|
3
7
|
import WebSocket from 'isomorphic-ws'
|
|
4
8
|
|
|
5
9
|
async function runRPC() {
|
|
@@ -9,18 +13,26 @@ async function runRPC() {
|
|
|
9
13
|
const channel = new WebSocketConn(ws, 'outbound')
|
|
10
14
|
const client = channel.buildClient()
|
|
11
15
|
|
|
16
|
+
console.log('Running RpcStream test via WebSocket..')
|
|
17
|
+
await runRpcStreamTest(client)
|
|
18
|
+
|
|
12
19
|
console.log('Running client test via WebSocket..')
|
|
13
20
|
await runClientTest(client)
|
|
14
21
|
|
|
15
|
-
console.log('Running
|
|
16
|
-
await
|
|
22
|
+
console.log('Running abort controller test via WebSocket..')
|
|
23
|
+
await runAbortControllerTest(client)
|
|
17
24
|
}
|
|
18
25
|
|
|
26
|
+
process.on('unhandledRejection', (ev) => {
|
|
27
|
+
console.error('Unhandled rejection', ev)
|
|
28
|
+
throw ev
|
|
29
|
+
})
|
|
30
|
+
|
|
19
31
|
runRPC()
|
|
20
32
|
.then(() => {
|
|
21
33
|
process.exit(0)
|
|
22
34
|
})
|
|
23
35
|
.catch((err) => {
|
|
24
|
-
console.error(err)
|
|
36
|
+
console.error('runRPC threw error', err)
|
|
25
37
|
process.exit(1)
|
|
26
38
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "starpc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Streaming protobuf RPC service protocol over any two-way channel.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -60,33 +60,33 @@
|
|
|
60
60
|
"singleQuote": true
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@aperturerobotics/ts-common": "^0.
|
|
64
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
65
|
-
"@typescript-eslint/parser": "^5.
|
|
63
|
+
"@aperturerobotics/ts-common": "^0.3.1",
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "^5.46.1",
|
|
65
|
+
"@typescript-eslint/parser": "^5.46.1",
|
|
66
66
|
"bufferutil": "^4.0.7",
|
|
67
67
|
"depcheck": "^1.4.3",
|
|
68
|
-
"esbuild": "^0.
|
|
69
|
-
"eslint": "^8.
|
|
68
|
+
"esbuild": "^0.16.7",
|
|
69
|
+
"eslint": "^8.29.0",
|
|
70
70
|
"eslint-config-prettier": "^8.5.0",
|
|
71
|
-
"prettier": "^2.8.
|
|
71
|
+
"prettier": "^2.8.1",
|
|
72
72
|
"rimraf": "^3.0.2",
|
|
73
|
-
"ts-proto": "^1.
|
|
74
|
-
"typescript": "^4.9.
|
|
73
|
+
"ts-proto": "^1.136.0",
|
|
74
|
+
"typescript": "^4.9.4",
|
|
75
75
|
"utf-8-validate": "^5.0.10"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@chainsafe/libp2p-yamux": "^3.0.3",
|
|
79
|
-
"@libp2p/interface-connection": "^3.0.
|
|
80
|
-
"@libp2p/interface-stream-muxer": "^3.0.
|
|
79
|
+
"@libp2p/interface-connection": "^3.0.4",
|
|
80
|
+
"@libp2p/interface-stream-muxer": "^3.0.2",
|
|
81
81
|
"event-iterator": "^2.0.0",
|
|
82
82
|
"is-promise": "^4.0.0",
|
|
83
83
|
"isomorphic-ws": "^5.0.0",
|
|
84
84
|
"it-first": "^2.0.0",
|
|
85
85
|
"it-length-prefixed": "^8.0.3",
|
|
86
|
-
"it-pipe": "^2.0.
|
|
86
|
+
"it-pipe": "^2.0.5",
|
|
87
87
|
"it-pushable": "^3.1.0",
|
|
88
88
|
"it-stream-types": "^1.0.4",
|
|
89
|
-
"it-ws": "^5.0.
|
|
89
|
+
"it-ws": "^5.0.6",
|
|
90
90
|
"long": "^5.2.1",
|
|
91
91
|
"patch-package": "^6.5.0",
|
|
92
92
|
"protobufjs": "^7.1.2",
|
package/srpc/client.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pipe } from 'it-pipe'
|
|
2
2
|
import { pushable, Pushable } from 'it-pushable'
|
|
3
3
|
|
|
4
|
+
import { ERR_RPC_ABORT } from './errors.js'
|
|
4
5
|
import type { TsProtoRpc } from './ts-proto-rpc.js'
|
|
5
6
|
import type { OpenStreamFunc } from './stream.js'
|
|
6
7
|
import { ClientRPC } from './client-rpc.js'
|
|
@@ -32,9 +33,10 @@ export class Client implements TsProtoRpc {
|
|
|
32
33
|
public async request(
|
|
33
34
|
service: string,
|
|
34
35
|
method: string,
|
|
35
|
-
data: Uint8Array
|
|
36
|
+
data: Uint8Array,
|
|
37
|
+
abortSignal?: AbortSignal
|
|
36
38
|
): Promise<Uint8Array> {
|
|
37
|
-
const call = await this.startRpc(service, method, data)
|
|
39
|
+
const call = await this.startRpc(service, method, data, abortSignal)
|
|
38
40
|
for await (const data of call.rpcDataSource) {
|
|
39
41
|
call.close()
|
|
40
42
|
return data
|
|
@@ -48,9 +50,10 @@ export class Client implements TsProtoRpc {
|
|
|
48
50
|
public async clientStreamingRequest(
|
|
49
51
|
service: string,
|
|
50
52
|
method: string,
|
|
51
|
-
data: AsyncIterable<Uint8Array
|
|
53
|
+
data: AsyncIterable<Uint8Array>,
|
|
54
|
+
abortSignal?: AbortSignal
|
|
52
55
|
): Promise<Uint8Array> {
|
|
53
|
-
const call = await this.startRpc(service, method, null)
|
|
56
|
+
const call = await this.startRpc(service, method, null, abortSignal)
|
|
54
57
|
call.writeCallDataFromSource(data)
|
|
55
58
|
for await (const data of call.rpcDataSource) {
|
|
56
59
|
call.close()
|
|
@@ -65,10 +68,11 @@ export class Client implements TsProtoRpc {
|
|
|
65
68
|
public serverStreamingRequest(
|
|
66
69
|
service: string,
|
|
67
70
|
method: string,
|
|
68
|
-
data: Uint8Array
|
|
71
|
+
data: Uint8Array,
|
|
72
|
+
abortSignal?: AbortSignal
|
|
69
73
|
): AsyncIterable<Uint8Array> {
|
|
70
74
|
const serverData: Pushable<Uint8Array> = pushable({ objectMode: true })
|
|
71
|
-
this.startRpc(service, method, data)
|
|
75
|
+
this.startRpc(service, method, data, abortSignal)
|
|
72
76
|
.then(async (call) => {
|
|
73
77
|
return writeToPushable(call.rpcDataSource, serverData)
|
|
74
78
|
})
|
|
@@ -80,10 +84,11 @@ export class Client implements TsProtoRpc {
|
|
|
80
84
|
public bidirectionalStreamingRequest(
|
|
81
85
|
service: string,
|
|
82
86
|
method: string,
|
|
83
|
-
data: AsyncIterable<Uint8Array
|
|
87
|
+
data: AsyncIterable<Uint8Array>,
|
|
88
|
+
abortSignal?: AbortSignal
|
|
84
89
|
): AsyncIterable<Uint8Array> {
|
|
85
90
|
const serverData: Pushable<Uint8Array> = pushable({ objectMode: true })
|
|
86
|
-
this.startRpc(service, method, null)
|
|
91
|
+
this.startRpc(service, method, null, abortSignal)
|
|
87
92
|
.then(async (call) => {
|
|
88
93
|
call.writeCallDataFromSource(data)
|
|
89
94
|
try {
|
|
@@ -105,11 +110,18 @@ export class Client implements TsProtoRpc {
|
|
|
105
110
|
private async startRpc(
|
|
106
111
|
rpcService: string,
|
|
107
112
|
rpcMethod: string,
|
|
108
|
-
data: Uint8Array | null
|
|
113
|
+
data: Uint8Array | null,
|
|
114
|
+
abortSignal?: AbortSignal
|
|
109
115
|
): Promise<ClientRPC> {
|
|
116
|
+
if (abortSignal?.aborted) {
|
|
117
|
+
throw new Error(ERR_RPC_ABORT)
|
|
118
|
+
}
|
|
110
119
|
const openStreamFn = await this.openStreamCtr.wait()
|
|
111
120
|
const conn = await openStreamFn()
|
|
112
121
|
const call = new ClientRPC(rpcService, rpcMethod)
|
|
122
|
+
abortSignal?.addEventListener('abort', () => {
|
|
123
|
+
call.close(new Error(ERR_RPC_ABORT))
|
|
124
|
+
})
|
|
113
125
|
pipe(
|
|
114
126
|
conn,
|
|
115
127
|
parseLengthPrefixTransform(),
|
package/srpc/common-rpc.ts
CHANGED
|
@@ -74,9 +74,9 @@ export class CommonRPC {
|
|
|
74
74
|
public async writeCallDataFromSource(dataSource: AsyncIterable<Uint8Array>) {
|
|
75
75
|
try {
|
|
76
76
|
for await (const data of dataSource) {
|
|
77
|
-
this.writeCallData(data)
|
|
77
|
+
await this.writeCallData(data)
|
|
78
78
|
}
|
|
79
|
-
this.writeCallData(undefined, true)
|
|
79
|
+
await this.writeCallData(undefined, true)
|
|
80
80
|
} catch (err) {
|
|
81
81
|
this.close(err as Error)
|
|
82
82
|
}
|
|
@@ -160,7 +160,8 @@ export class CommonRPC {
|
|
|
160
160
|
await this.writeCallCancel()
|
|
161
161
|
} finally {
|
|
162
162
|
this._rpcDataSource.end(err)
|
|
163
|
-
|
|
163
|
+
// note: don't pass error to _source here.
|
|
164
|
+
this._source.end()
|
|
164
165
|
}
|
|
165
166
|
}
|
|
166
167
|
|
package/srpc/errors.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// ERR_RPC_ABORT is returned if the RPC was aborted.
|
|
2
|
+
export const ERR_RPC_ABORT = 'ERR_RPC_ABORT'
|
|
3
|
+
|
|
4
|
+
// isAbortError checks if the error object is ERR_RPC_ABORT.
|
|
5
|
+
export function isAbortError(err: unknown): boolean {
|
|
6
|
+
if (typeof err !== 'object') {
|
|
7
|
+
return false
|
|
8
|
+
}
|
|
9
|
+
const message = (err as Error).message
|
|
10
|
+
return message === ERR_RPC_ABORT
|
|
11
|
+
}
|
package/srpc/index.ts
CHANGED
package/srpc/server-rpc.ts
CHANGED
|
@@ -45,11 +45,13 @@ export class ServerRPC extends CommonRPC {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// invokeRPC starts invoking the RPC handler.
|
|
48
|
-
private invokeRPC(invokeFn: InvokeFn) {
|
|
48
|
+
private async invokeRPC(invokeFn: InvokeFn) {
|
|
49
49
|
const dataSink = this._createDataSink()
|
|
50
|
-
|
|
51
|
-
this.
|
|
52
|
-
})
|
|
50
|
+
try {
|
|
51
|
+
await invokeFn(this.rpcDataSource, dataSink)
|
|
52
|
+
} catch (err) {
|
|
53
|
+
this.close(err as Error)
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
// _createDataSink creates a sink for outgoing data packets.
|
package/srpc/ts-proto-rpc.ts
CHANGED
|
@@ -4,24 +4,28 @@ export interface TsProtoRpc {
|
|
|
4
4
|
request(
|
|
5
5
|
service: string,
|
|
6
6
|
method: string,
|
|
7
|
-
data: Uint8Array
|
|
7
|
+
data: Uint8Array,
|
|
8
|
+
abortSignal?: AbortSignal
|
|
8
9
|
): Promise<Uint8Array>
|
|
9
10
|
// clientStreamingRequest fires a one-way client->server streaming request.
|
|
10
11
|
clientStreamingRequest(
|
|
11
12
|
service: string,
|
|
12
13
|
method: string,
|
|
13
|
-
data: AsyncIterable<Uint8Array
|
|
14
|
+
data: AsyncIterable<Uint8Array>,
|
|
15
|
+
abortSignal?: AbortSignal
|
|
14
16
|
): Promise<Uint8Array>
|
|
15
17
|
// serverStreamingRequest fires a one-way server->client streaming request.
|
|
16
18
|
serverStreamingRequest(
|
|
17
19
|
service: string,
|
|
18
20
|
method: string,
|
|
19
|
-
data: Uint8Array
|
|
21
|
+
data: Uint8Array,
|
|
22
|
+
abortSignal?: AbortSignal
|
|
20
23
|
): AsyncIterable<Uint8Array>
|
|
21
24
|
// bidirectionalStreamingRequest implements a two-way streaming request.
|
|
22
25
|
bidirectionalStreamingRequest(
|
|
23
26
|
service: string,
|
|
24
27
|
method: string,
|
|
25
|
-
data: AsyncIterable<Uint8Array
|
|
28
|
+
data: AsyncIterable<Uint8Array>,
|
|
29
|
+
abortSignal?: AbortSignal
|
|
26
30
|
): AsyncIterable<Uint8Array>
|
|
27
31
|
}
|