starpc 0.51.0 → 0.52.1
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/cmd/protoc-gen-es-starpc/typescript.ts +37 -0
- package/dist/cmd/protoc-gen-es-starpc/typescript.js +24 -0
- package/dist/echo/client-test.d.ts +1 -1
- package/dist/echo/client-test.js +110 -2
- package/dist/echo/echo_srpc.pb.d.ts +44 -1
- package/dist/echo/server.d.ts +9 -8
- package/dist/echo/server.js +6 -6
- package/dist/integration/cross-language/tcp-packet-stream.d.ts +3 -0
- package/dist/integration/cross-language/tcp-packet-stream.js +112 -0
- package/dist/integration/cross-language/tcp-packet-stream.test.d.ts +1 -0
- package/dist/integration/cross-language/tcp-packet-stream.test.js +121 -0
- package/dist/integration/cross-language/ts-client.js +50 -37
- package/dist/integration/cross-language/ts-server.js +1 -36
- package/dist/mock/mock_srpc.pb.d.ts +14 -1
- package/dist/rpcstream/rpcstream.d.ts +5 -1
- package/dist/rpcstream/rpcstream.js +75 -28
- package/dist/rpcstream/rpcstream.test.d.ts +1 -0
- package/dist/rpcstream/rpcstream.test.js +92 -0
- package/dist/srpc/channel.js +6 -3
- package/dist/srpc/channel.test.js +20 -1
- package/dist/srpc/client.js +18 -4
- package/dist/srpc/common-rpc.test.js +2 -0
- package/dist/srpc/handler.d.ts +12 -3
- package/dist/srpc/index.d.ts +2 -0
- package/dist/srpc/index.js +1 -0
- package/dist/srpc/invoker.d.ts +2 -1
- package/dist/srpc/invoker.js +2 -2
- package/dist/srpc/packet-codec.test.d.ts +1 -0
- package/dist/srpc/packet-codec.test.js +75 -0
- package/dist/srpc/packet.d.ts +1 -1
- package/dist/srpc/packet.js +11 -1
- package/dist/srpc/server-context.d.ts +11 -0
- package/dist/srpc/server-context.js +28 -0
- package/dist/srpc/server-rpc.js +3 -1
- package/dist/srpc/server.js +19 -6
- package/dist/srpc/server.test.js +78 -6
- package/dist/srpc/stream.d.ts +4 -1
- package/dist/srpc/stream.js +62 -3
- package/dist/srpc/stream.test.js +110 -1
- package/dist/srpc/termination.d.ts +27 -0
- package/dist/srpc/termination.js +56 -0
- package/dist/srpc/termination.test.d.ts +1 -0
- package/dist/srpc/termination.test.js +24 -0
- package/dist/srpc/watchdog.test.js +1 -0
- package/dist/testdata/packet-codec-vectors.json +64 -0
- package/echo/client-test.ts +124 -2
- package/echo/echo_pb2.py +40 -0
- package/echo/echo_pb2.pyi +13 -0
- package/echo/echo_srpc.pb.ts +74 -0
- package/echo/echo_srpc.py +306 -0
- package/echo/echo_srpc.pyi +85 -0
- package/echo/server.ts +24 -5
- package/go.mod +2 -2
- package/go.sum +14 -0
- package/integration/cross-language/go-client/main.go +79 -3
- package/integration/cross-language/python-client.py +146 -0
- package/integration/cross-language/python-server.py +140 -0
- package/integration/cross-language/run.bash +190 -65
- package/integration/cross-language/tcp-packet-stream.test.ts +154 -0
- package/integration/cross-language/tcp-packet-stream.ts +121 -0
- package/integration/cross-language/ts-client.ts +62 -40
- package/integration/cross-language/ts-server.ts +1 -45
- package/mock/mock_pb2.py +38 -0
- package/mock/mock_pb2.pyi +11 -0
- package/mock/mock_srpc.pb.ts +19 -1
- package/mock/mock_srpc.py +71 -0
- package/mock/mock_srpc.pyi +27 -0
- package/package.json +20 -6
- package/srpc/__init__.py +0 -0
- package/srpc/channel.test.ts +21 -1
- package/srpc/channel.ts +7 -3
- package/srpc/client.ts +20 -4
- package/srpc/codec.rs +6 -0
- package/srpc/common-rpc.test.ts +2 -0
- package/srpc/handler.ts +54 -4
- package/srpc/index.ts +7 -0
- package/srpc/invoker.ts +23 -6
- package/srpc/packet-codec-vectors_test.go +195 -0
- package/srpc/packet-codec.test.ts +139 -0
- package/srpc/packet-rw.go +9 -2
- package/srpc/packet.ts +15 -2
- package/srpc/py.typed +0 -0
- package/srpc/rpcproto_pb2.py +40 -0
- package/srpc/rpcproto_pb2.pyi +40 -0
- package/srpc/server-context.ts +55 -0
- package/srpc/server-rpc.ts +4 -1
- package/srpc/server.test.ts +100 -5
- package/srpc/server.ts +22 -6
- package/srpc/stream.test.ts +132 -1
- package/srpc/stream.ts +65 -9
- package/srpc/termination.test.ts +30 -0
- package/srpc/termination.ts +70 -0
- package/srpc/watchdog.test.ts +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"max_message_size": 10000000,
|
|
4
|
+
"frame_prefix": "uint32 little-endian",
|
|
5
|
+
"cases": [
|
|
6
|
+
{
|
|
7
|
+
"name": "call_start_data",
|
|
8
|
+
"packet_hex": "0a120a0373766312066d6574686f641a03616263",
|
|
9
|
+
"frame_hex": "140000000a120a0373766312066d6574686f641a03616263"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "call_start_absent_empty",
|
|
13
|
+
"packet_hex": "0a0d0a0373766312066d6574686f64",
|
|
14
|
+
"frame_hex": "0f0000000a0d0a0373766312066d6574686f64"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "call_start_present_empty",
|
|
18
|
+
"packet_hex": "0a0f0a0373766312066d6574686f642001",
|
|
19
|
+
"frame_hex": "110000000a0f0a0373766312066d6574686f642001"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "call_data_terminal",
|
|
23
|
+
"packet_hex": "12070a036f75741801",
|
|
24
|
+
"frame_hex": "0900000012070a036f75741801"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "call_data_error",
|
|
28
|
+
"packet_hex": "120a180122066661696c6564",
|
|
29
|
+
"frame_hex": "0c000000120a180122066661696c6564"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "call_cancel",
|
|
33
|
+
"packet_hex": "1801",
|
|
34
|
+
"frame_hex": "020000001801"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "malformed_complete",
|
|
38
|
+
"frame_hex": "030000000a01ff",
|
|
39
|
+
"expect_error": "malformed_packet"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "invalid_zero_length",
|
|
43
|
+
"frame_hex": "00000000",
|
|
44
|
+
"expect_error": "invalid_length"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "invalid_oversized_prefix",
|
|
48
|
+
"frame_hex": "81969800",
|
|
49
|
+
"expect_error": "oversized_frame"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "invalid_empty_packet",
|
|
53
|
+
"packet_hex": "",
|
|
54
|
+
"expect_error": "empty_packet"
|
|
55
|
+
},
|
|
56
|
+
{ "name": "invalid_empty_service_id", "expect_error": "empty_service_id" },
|
|
57
|
+
{ "name": "invalid_empty_method_id", "expect_error": "empty_method_id" },
|
|
58
|
+
{
|
|
59
|
+
"name": "truncated_body",
|
|
60
|
+
"frame_hex": "040000000a01",
|
|
61
|
+
"expect_error": "truncated_frame"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
package/echo/client-test.ts
CHANGED
|
@@ -2,7 +2,10 @@ import { Client, ERR_RPC_ABORT } from '../srpc/index.js'
|
|
|
2
2
|
import { EchoMsg } from './echo.pb.js'
|
|
3
3
|
import { EchoerClient } from './echo_srpc.pb.js'
|
|
4
4
|
import { pushable } from 'it-pushable'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
buildRpcStreamOpenStream,
|
|
7
|
+
openRpcStream,
|
|
8
|
+
} from '../rpcstream/rpcstream.js'
|
|
6
9
|
import { Message } from '@aptre/protobuf-es-lite'
|
|
7
10
|
|
|
8
11
|
export async function runClientTest(client: Client) {
|
|
@@ -89,8 +92,19 @@ export async function runAbortControllerTest(client: Client) {
|
|
|
89
92
|
})
|
|
90
93
|
}
|
|
91
94
|
|
|
95
|
+
function requireError(
|
|
96
|
+
error: unknown,
|
|
97
|
+
label: string,
|
|
98
|
+
fragments: string[],
|
|
99
|
+
): void {
|
|
100
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
101
|
+
if (!fragments.some((fragment) => message.includes(fragment))) {
|
|
102
|
+
throw new Error(`${label} returned unexpected error: ${message}`)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
92
106
|
// runRpcStreamTest tests a RPCStream.
|
|
93
|
-
export async function runRpcStreamTest(client: Client) {
|
|
107
|
+
export async function runRpcStreamTest(client: Client, release = false) {
|
|
94
108
|
console.log('Calling RpcStream to open a RPC stream client...')
|
|
95
109
|
const service = new EchoerClient(client)
|
|
96
110
|
const openStreamFn = buildRpcStreamOpenStream(
|
|
@@ -106,4 +120,112 @@ export async function runRpcStreamTest(client: Client) {
|
|
|
106
120
|
|
|
107
121
|
console.log('Running client test over RPC stream...')
|
|
108
122
|
await runClientTest(proxiedClient)
|
|
123
|
+
|
|
124
|
+
if (release) {
|
|
125
|
+
let unknownRejected = false
|
|
126
|
+
try {
|
|
127
|
+
await openRpcStream('missing', service.RpcStream.bind(service), true)
|
|
128
|
+
} catch (error) {
|
|
129
|
+
unknownRejected = true
|
|
130
|
+
requireError(error, 'unknown component', ['unknown component: missing'])
|
|
131
|
+
}
|
|
132
|
+
if (!unknownRejected) {
|
|
133
|
+
throw new Error('unknown component unexpectedly succeeded')
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let methodRejected = false
|
|
138
|
+
try {
|
|
139
|
+
await proxiedClient.request('missing.Service', 'Missing', new Uint8Array())
|
|
140
|
+
} catch (error) {
|
|
141
|
+
methodRejected = true
|
|
142
|
+
requireError(error, 'unknown nested method', [
|
|
143
|
+
'missing.Service',
|
|
144
|
+
'unimplemented',
|
|
145
|
+
])
|
|
146
|
+
}
|
|
147
|
+
if (!methodRejected) {
|
|
148
|
+
throw new Error('unknown nested method unexpectedly succeeded')
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (release) {
|
|
152
|
+
const terminalService = new EchoerClient(proxiedClient)
|
|
153
|
+
let terminalFailed = false
|
|
154
|
+
try {
|
|
155
|
+
await terminalService.Echo({ body: '__nested_error__' })
|
|
156
|
+
} catch (error) {
|
|
157
|
+
terminalFailed = true
|
|
158
|
+
requireError(error, 'terminal nested error', ['nested terminal error'])
|
|
159
|
+
}
|
|
160
|
+
if (!terminalFailed) {
|
|
161
|
+
throw new Error('terminal nested error unexpectedly succeeded')
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (release) {
|
|
166
|
+
const releaseClient = new Client(
|
|
167
|
+
buildRpcStreamOpenStream('release', service.RpcStream.bind(service)),
|
|
168
|
+
)
|
|
169
|
+
let releaseFailed = false
|
|
170
|
+
const releaseService = new EchoerClient(releaseClient)
|
|
171
|
+
try {
|
|
172
|
+
await releaseService.Echo({ body: '__nested_release__' })
|
|
173
|
+
} catch (error) {
|
|
174
|
+
releaseFailed = true
|
|
175
|
+
requireError(error, 'release during active call', [
|
|
176
|
+
'closed before completion',
|
|
177
|
+
'stream closed',
|
|
178
|
+
'abort',
|
|
179
|
+
'cancel',
|
|
180
|
+
])
|
|
181
|
+
}
|
|
182
|
+
if (!releaseFailed) {
|
|
183
|
+
throw new Error('release during active call unexpectedly succeeded')
|
|
184
|
+
}
|
|
185
|
+
const releaseStatus = await service.Echo({
|
|
186
|
+
body: '__nested_release_status__',
|
|
187
|
+
})
|
|
188
|
+
if (releaseStatus.body !== 'released') {
|
|
189
|
+
throw new Error(`release completion returned ${releaseStatus.body}`)
|
|
190
|
+
}
|
|
191
|
+
let releasedRejected = false
|
|
192
|
+
try {
|
|
193
|
+
await releaseService.Echo({})
|
|
194
|
+
} catch (error) {
|
|
195
|
+
releasedRejected = true
|
|
196
|
+
requireError(error, 'released component', ['unknown component: release'])
|
|
197
|
+
}
|
|
198
|
+
if (!releasedRejected) {
|
|
199
|
+
throw new Error('released component unexpectedly remained available')
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const cancelled = new AbortController()
|
|
204
|
+
const cancelledStream = proxiedClient.bidirectionalStreamingRequest(
|
|
205
|
+
'echo.Echoer',
|
|
206
|
+
'EchoBidiStream',
|
|
207
|
+
(async function* () {
|
|
208
|
+
yield new Uint8Array()
|
|
209
|
+
await new Promise(() => undefined)
|
|
210
|
+
})(),
|
|
211
|
+
cancelled.signal,
|
|
212
|
+
)
|
|
213
|
+
const cancelledIterator = cancelledStream[Symbol.asyncIterator]()
|
|
214
|
+
const firstNestedResponse = await cancelledIterator.next()
|
|
215
|
+
if (firstNestedResponse.done) {
|
|
216
|
+
throw new Error('nested cancellation call ended before its first response')
|
|
217
|
+
}
|
|
218
|
+
cancelled.abort()
|
|
219
|
+
let cancelRejected = false
|
|
220
|
+
try {
|
|
221
|
+
while (!(await cancelledIterator.next()).done) {
|
|
222
|
+
// Drain until the abort reaches the nested call.
|
|
223
|
+
}
|
|
224
|
+
} catch (error) {
|
|
225
|
+
cancelRejected = true
|
|
226
|
+
requireError(error, 'nested cancellation', [ERR_RPC_ABORT])
|
|
227
|
+
}
|
|
228
|
+
if (!cancelRejected) {
|
|
229
|
+
throw new Error('nested cancellation unexpectedly completed normally')
|
|
230
|
+
}
|
|
109
231
|
}
|
package/echo/echo_pb2.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: github.com/aperturerobotics/starpc/echo/echo.proto
|
|
5
|
+
# Protobuf Python Version: 6.33.4
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
33,
|
|
16
|
+
4,
|
|
17
|
+
'',
|
|
18
|
+
'github.com/aperturerobotics/starpc/echo/echo.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
from rpcstream import rpcstream_pb2 as github_dot_com_dot_aperturerobotics_dot_starpc_dot_rpcstream_dot_rpcstream__pb2
|
|
26
|
+
from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2github.com/aperturerobotics/starpc/echo/echo.proto\x12\x04\x65\x63ho\x1a<github.com/aperturerobotics/starpc/rpcstream/rpcstream.proto\x1a\x1bgoogle/protobuf/empty.proto\"\x17\n\x07\x45\x63hoMsg\x12\x0c\n\x04\x62ody\x18\x01 \x01(\t2\xd0\x02\n\x06\x45\x63hoer\x12$\n\x04\x45\x63ho\x12\r.echo.EchoMsg\x1a\r.echo.EchoMsg\x12\x32\n\x10\x45\x63hoServerStream\x12\r.echo.EchoMsg\x1a\r.echo.EchoMsg0\x01\x12\x32\n\x10\x45\x63hoClientStream\x12\r.echo.EchoMsg\x1a\r.echo.EchoMsg(\x01\x12\x32\n\x0e\x45\x63hoBidiStream\x12\r.echo.EchoMsg\x1a\r.echo.EchoMsg(\x01\x30\x01\x12G\n\tRpcStream\x12\x1a.rpcstream.RpcStreamPacket\x1a\x1a.rpcstream.RpcStreamPacket(\x01\x30\x01\x12;\n\tDoNothing\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Emptyb\x06proto3')
|
|
30
|
+
|
|
31
|
+
_globals = globals()
|
|
32
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
33
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'github.com.aperturerobotics.starpc.echo.echo_pb2', _globals)
|
|
34
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
35
|
+
DESCRIPTOR._loaded_options = None
|
|
36
|
+
_globals['_ECHOMSG']._serialized_start=151
|
|
37
|
+
_globals['_ECHOMSG']._serialized_end=174
|
|
38
|
+
_globals['_ECHOER']._serialized_start=177
|
|
39
|
+
_globals['_ECHOER']._serialized_end=513
|
|
40
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from rpcstream import rpcstream_pb2 as _rpcstream_pb2
|
|
2
|
+
from google.protobuf import empty_pb2 as _empty_pb2
|
|
3
|
+
from google.protobuf import descriptor as _descriptor
|
|
4
|
+
from google.protobuf import message as _message
|
|
5
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional
|
|
6
|
+
|
|
7
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
8
|
+
|
|
9
|
+
class EchoMsg(_message.Message):
|
|
10
|
+
__slots__ = ("body",)
|
|
11
|
+
BODY_FIELD_NUMBER: _ClassVar[int]
|
|
12
|
+
body: str
|
|
13
|
+
def __init__(self, body: _Optional[str] = ...) -> None: ...
|
package/echo/echo_srpc.pb.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
buildEncodeMessageTransform,
|
|
12
12
|
MessageStream,
|
|
13
13
|
ProtoRpc,
|
|
14
|
+
ServerContext,
|
|
14
15
|
} from 'starpc'
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -151,6 +152,79 @@ export interface Echoer {
|
|
|
151
152
|
DoNothing(request: Empty, abortSignal?: AbortSignal): Promise<Empty>
|
|
152
153
|
}
|
|
153
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Echoer service returns the given message.
|
|
157
|
+
*
|
|
158
|
+
* @generated from service echo.Echoer
|
|
159
|
+
*/
|
|
160
|
+
export interface EchoerHandler {
|
|
161
|
+
/**
|
|
162
|
+
* Echo returns the given message.
|
|
163
|
+
*
|
|
164
|
+
* @generated from rpc echo.Echoer.Echo
|
|
165
|
+
*/
|
|
166
|
+
Echo(
|
|
167
|
+
request: EchoMsg,
|
|
168
|
+
abortSignal: AbortSignal,
|
|
169
|
+
context: ServerContext,
|
|
170
|
+
): Promise<EchoMsg>
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* EchoServerStream is an example of a server -> client one-way stream.
|
|
174
|
+
*
|
|
175
|
+
* @generated from rpc echo.Echoer.EchoServerStream
|
|
176
|
+
*/
|
|
177
|
+
EchoServerStream(
|
|
178
|
+
request: EchoMsg,
|
|
179
|
+
abortSignal: AbortSignal,
|
|
180
|
+
context: ServerContext,
|
|
181
|
+
): MessageStream<EchoMsg>
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* EchoClientStream is an example of client->server one-way stream.
|
|
185
|
+
*
|
|
186
|
+
* @generated from rpc echo.Echoer.EchoClientStream
|
|
187
|
+
*/
|
|
188
|
+
EchoClientStream(
|
|
189
|
+
request: MessageStream<EchoMsg>,
|
|
190
|
+
abortSignal: AbortSignal,
|
|
191
|
+
context: ServerContext,
|
|
192
|
+
): Promise<EchoMsg>
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* EchoBidiStream is an example of a two-way stream.
|
|
196
|
+
*
|
|
197
|
+
* @generated from rpc echo.Echoer.EchoBidiStream
|
|
198
|
+
*/
|
|
199
|
+
EchoBidiStream(
|
|
200
|
+
request: MessageStream<EchoMsg>,
|
|
201
|
+
abortSignal: AbortSignal,
|
|
202
|
+
context: ServerContext,
|
|
203
|
+
): MessageStream<EchoMsg>
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* RpcStream opens a nested rpc call stream.
|
|
207
|
+
*
|
|
208
|
+
* @generated from rpc echo.Echoer.RpcStream
|
|
209
|
+
*/
|
|
210
|
+
RpcStream(
|
|
211
|
+
request: MessageStream<RpcStreamPacket>,
|
|
212
|
+
abortSignal: AbortSignal,
|
|
213
|
+
context: ServerContext,
|
|
214
|
+
): MessageStream<RpcStreamPacket>
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* DoNothing does nothing.
|
|
218
|
+
*
|
|
219
|
+
* @generated from rpc echo.Echoer.DoNothing
|
|
220
|
+
*/
|
|
221
|
+
DoNothing(
|
|
222
|
+
request: Empty,
|
|
223
|
+
abortSignal: AbortSignal,
|
|
224
|
+
context: ServerContext,
|
|
225
|
+
): Promise<Empty>
|
|
226
|
+
}
|
|
227
|
+
|
|
154
228
|
export const EchoerServiceName = EchoerDefinition.typeName
|
|
155
229
|
|
|
156
230
|
export class EchoerClient implements Echoer {
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import AsyncIterable, AsyncIterator
|
|
4
|
+
from typing import Protocol
|
|
5
|
+
|
|
6
|
+
from google.protobuf import empty_pb2 as _google_protobuf_empty_pb2
|
|
7
|
+
|
|
8
|
+
from echo import (
|
|
9
|
+
echo_pb2 as _github_com_aperturerobotics_starpc_echo_echo_pb2,
|
|
10
|
+
)
|
|
11
|
+
from rpcstream import (
|
|
12
|
+
rpcstream_pb2 as _github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2,
|
|
13
|
+
)
|
|
14
|
+
from starpc.call import Call, CallProtocolError
|
|
15
|
+
from starpc.client import Client
|
|
16
|
+
from starpc.server import ServiceRegistry
|
|
17
|
+
from starpc.service import MethodDescriptor, ServiceDescriptor, bidirectional_bytes
|
|
18
|
+
|
|
19
|
+
ECHOER_SERVICE = ServiceDescriptor(
|
|
20
|
+
"echo.Echoer",
|
|
21
|
+
(
|
|
22
|
+
MethodDescriptor(
|
|
23
|
+
"Echo",
|
|
24
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
25
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
26
|
+
False,
|
|
27
|
+
False,
|
|
28
|
+
),
|
|
29
|
+
MethodDescriptor(
|
|
30
|
+
"EchoServerStream",
|
|
31
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
32
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
33
|
+
False,
|
|
34
|
+
True,
|
|
35
|
+
),
|
|
36
|
+
MethodDescriptor(
|
|
37
|
+
"EchoClientStream",
|
|
38
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
39
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
40
|
+
True,
|
|
41
|
+
False,
|
|
42
|
+
),
|
|
43
|
+
MethodDescriptor(
|
|
44
|
+
"EchoBidiStream",
|
|
45
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
46
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg,
|
|
47
|
+
True,
|
|
48
|
+
True,
|
|
49
|
+
),
|
|
50
|
+
MethodDescriptor(
|
|
51
|
+
"RpcStream",
|
|
52
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket,
|
|
53
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket,
|
|
54
|
+
True,
|
|
55
|
+
True,
|
|
56
|
+
),
|
|
57
|
+
MethodDescriptor(
|
|
58
|
+
"DoNothing",
|
|
59
|
+
_google_protobuf_empty_pb2.Empty,
|
|
60
|
+
_google_protobuf_empty_pb2.Empty,
|
|
61
|
+
False,
|
|
62
|
+
False,
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class EchoerClient:
|
|
69
|
+
def __init__(self, client: Client, service: str | None = None) -> None:
|
|
70
|
+
self._client = client
|
|
71
|
+
self._service = service or "echo.Echoer"
|
|
72
|
+
|
|
73
|
+
async def echo(
|
|
74
|
+
self, request: _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
75
|
+
) -> _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg:
|
|
76
|
+
call = await self._client.open_call(
|
|
77
|
+
self._service, "Echo", request.SerializeToString(deterministic=True)
|
|
78
|
+
)
|
|
79
|
+
try:
|
|
80
|
+
data = await call.receive()
|
|
81
|
+
if data is None:
|
|
82
|
+
raise CallProtocolError("missing unary response")
|
|
83
|
+
response = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
84
|
+
response.ParseFromString(data)
|
|
85
|
+
if await call.receive() is not None:
|
|
86
|
+
raise CallProtocolError("extra unary response")
|
|
87
|
+
return response
|
|
88
|
+
finally:
|
|
89
|
+
await call.aclose()
|
|
90
|
+
|
|
91
|
+
async def echo_server_stream(
|
|
92
|
+
self, request: _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
93
|
+
) -> AsyncIterator[_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg]:
|
|
94
|
+
call = await self._client.open_call(
|
|
95
|
+
self._service,
|
|
96
|
+
"EchoServerStream",
|
|
97
|
+
request.SerializeToString(deterministic=True),
|
|
98
|
+
)
|
|
99
|
+
try:
|
|
100
|
+
while True:
|
|
101
|
+
data = await call.receive()
|
|
102
|
+
if data is None:
|
|
103
|
+
return
|
|
104
|
+
response = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
105
|
+
response.ParseFromString(data)
|
|
106
|
+
yield response
|
|
107
|
+
finally:
|
|
108
|
+
await call.aclose()
|
|
109
|
+
|
|
110
|
+
async def echo_client_stream(
|
|
111
|
+
self,
|
|
112
|
+
requests: AsyncIterable[
|
|
113
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
114
|
+
],
|
|
115
|
+
) -> _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg:
|
|
116
|
+
call = await self._client.open_call(self._service, "EchoClientStream")
|
|
117
|
+
try:
|
|
118
|
+
async for request in requests:
|
|
119
|
+
await call.send(request.SerializeToString(deterministic=True))
|
|
120
|
+
await call.finish()
|
|
121
|
+
data = await call.receive()
|
|
122
|
+
if data is None:
|
|
123
|
+
raise CallProtocolError("missing client-stream response")
|
|
124
|
+
response = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
125
|
+
response.ParseFromString(data)
|
|
126
|
+
if await call.receive() is not None:
|
|
127
|
+
raise CallProtocolError("extra client-stream response")
|
|
128
|
+
return response
|
|
129
|
+
finally:
|
|
130
|
+
await call.aclose()
|
|
131
|
+
|
|
132
|
+
async def echo_bidi_stream(
|
|
133
|
+
self,
|
|
134
|
+
requests: AsyncIterable[
|
|
135
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
136
|
+
],
|
|
137
|
+
) -> AsyncIterator[_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg]:
|
|
138
|
+
call = await self._client.open_call(self._service, "EchoBidiStream")
|
|
139
|
+
|
|
140
|
+
async def encoded() -> AsyncIterator[bytes]:
|
|
141
|
+
async for request in requests:
|
|
142
|
+
yield request.SerializeToString(deterministic=True)
|
|
143
|
+
|
|
144
|
+
async for data in bidirectional_bytes(call, encoded()):
|
|
145
|
+
response = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
146
|
+
response.ParseFromString(data)
|
|
147
|
+
yield response
|
|
148
|
+
|
|
149
|
+
async def rpc_stream(
|
|
150
|
+
self,
|
|
151
|
+
requests: AsyncIterable[
|
|
152
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket
|
|
153
|
+
],
|
|
154
|
+
) -> AsyncIterator[
|
|
155
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket
|
|
156
|
+
]:
|
|
157
|
+
call = await self._client.open_call(self._service, "RpcStream")
|
|
158
|
+
|
|
159
|
+
async def encoded() -> AsyncIterator[bytes]:
|
|
160
|
+
async for request in requests:
|
|
161
|
+
yield request.SerializeToString(deterministic=True)
|
|
162
|
+
|
|
163
|
+
async for data in bidirectional_bytes(call, encoded()):
|
|
164
|
+
response = _github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket()
|
|
165
|
+
response.ParseFromString(data)
|
|
166
|
+
yield response
|
|
167
|
+
|
|
168
|
+
async def do_nothing(
|
|
169
|
+
self, request: _google_protobuf_empty_pb2.Empty
|
|
170
|
+
) -> _google_protobuf_empty_pb2.Empty:
|
|
171
|
+
call = await self._client.open_call(
|
|
172
|
+
self._service, "DoNothing", request.SerializeToString(deterministic=True)
|
|
173
|
+
)
|
|
174
|
+
try:
|
|
175
|
+
data = await call.receive()
|
|
176
|
+
if data is None:
|
|
177
|
+
raise CallProtocolError("missing unary response")
|
|
178
|
+
response = _google_protobuf_empty_pb2.Empty()
|
|
179
|
+
response.ParseFromString(data)
|
|
180
|
+
if await call.receive() is not None:
|
|
181
|
+
raise CallProtocolError("extra unary response")
|
|
182
|
+
return response
|
|
183
|
+
finally:
|
|
184
|
+
await call.aclose()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class EchoerServer(Protocol):
|
|
188
|
+
async def echo(
|
|
189
|
+
self, request: _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
190
|
+
) -> _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg: ...
|
|
191
|
+
def echo_server_stream(
|
|
192
|
+
self, request: _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
193
|
+
) -> AsyncIterator[_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg]: ...
|
|
194
|
+
async def echo_client_stream(
|
|
195
|
+
self,
|
|
196
|
+
requests: AsyncIterator[
|
|
197
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
198
|
+
],
|
|
199
|
+
) -> _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg: ...
|
|
200
|
+
def echo_bidi_stream(
|
|
201
|
+
self,
|
|
202
|
+
requests: AsyncIterator[
|
|
203
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
204
|
+
],
|
|
205
|
+
) -> AsyncIterator[_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg]: ...
|
|
206
|
+
def rpc_stream(
|
|
207
|
+
self,
|
|
208
|
+
requests: AsyncIterator[
|
|
209
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket
|
|
210
|
+
],
|
|
211
|
+
) -> AsyncIterator[
|
|
212
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket
|
|
213
|
+
]: ...
|
|
214
|
+
async def do_nothing(
|
|
215
|
+
self, request: _google_protobuf_empty_pb2.Empty
|
|
216
|
+
) -> _google_protobuf_empty_pb2.Empty: ...
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def register_echoer(
|
|
220
|
+
registry: ServiceRegistry,
|
|
221
|
+
implementation: EchoerServer,
|
|
222
|
+
service: str = "echo.Echoer",
|
|
223
|
+
) -> None:
|
|
224
|
+
async def echo_handler(call: Call) -> None:
|
|
225
|
+
first = await call.receive()
|
|
226
|
+
if first is None:
|
|
227
|
+
raise CallProtocolError("missing initial request")
|
|
228
|
+
request = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
229
|
+
request.ParseFromString(first)
|
|
230
|
+
response = await implementation.echo(request)
|
|
231
|
+
await call.send(response.SerializeToString(deterministic=True))
|
|
232
|
+
|
|
233
|
+
registry.register(service, "Echo", echo_handler)
|
|
234
|
+
|
|
235
|
+
async def echo_server_stream_handler(call: Call) -> None:
|
|
236
|
+
first = await call.receive()
|
|
237
|
+
if first is None:
|
|
238
|
+
raise CallProtocolError("missing initial request")
|
|
239
|
+
request = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
240
|
+
request.ParseFromString(first)
|
|
241
|
+
async for response in implementation.echo_server_stream(request):
|
|
242
|
+
await call.send(response.SerializeToString(deterministic=True))
|
|
243
|
+
|
|
244
|
+
registry.register(service, "EchoServerStream", echo_server_stream_handler)
|
|
245
|
+
|
|
246
|
+
async def echo_client_stream_handler(call: Call) -> None:
|
|
247
|
+
async def requests() -> AsyncIterator[
|
|
248
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
249
|
+
]:
|
|
250
|
+
while True:
|
|
251
|
+
data = await call.receive()
|
|
252
|
+
if data is None:
|
|
253
|
+
return
|
|
254
|
+
request = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
255
|
+
request.ParseFromString(data)
|
|
256
|
+
yield request
|
|
257
|
+
|
|
258
|
+
response = await implementation.echo_client_stream(requests())
|
|
259
|
+
await call.send(response.SerializeToString(deterministic=True))
|
|
260
|
+
|
|
261
|
+
registry.register(service, "EchoClientStream", echo_client_stream_handler)
|
|
262
|
+
|
|
263
|
+
async def echo_bidi_stream_handler(call: Call) -> None:
|
|
264
|
+
async def requests() -> AsyncIterator[
|
|
265
|
+
_github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg
|
|
266
|
+
]:
|
|
267
|
+
while True:
|
|
268
|
+
data = await call.receive()
|
|
269
|
+
if data is None:
|
|
270
|
+
return
|
|
271
|
+
request = _github_com_aperturerobotics_starpc_echo_echo_pb2.EchoMsg()
|
|
272
|
+
request.ParseFromString(data)
|
|
273
|
+
yield request
|
|
274
|
+
|
|
275
|
+
async for response in implementation.echo_bidi_stream(requests()):
|
|
276
|
+
await call.send(response.SerializeToString(deterministic=True))
|
|
277
|
+
|
|
278
|
+
registry.register(service, "EchoBidiStream", echo_bidi_stream_handler)
|
|
279
|
+
|
|
280
|
+
async def rpc_stream_handler(call: Call) -> None:
|
|
281
|
+
async def requests() -> AsyncIterator[
|
|
282
|
+
_github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket
|
|
283
|
+
]:
|
|
284
|
+
while True:
|
|
285
|
+
data = await call.receive()
|
|
286
|
+
if data is None:
|
|
287
|
+
return
|
|
288
|
+
request = _github_com_aperturerobotics_starpc_rpcstream_rpcstream_pb2.RpcStreamPacket()
|
|
289
|
+
request.ParseFromString(data)
|
|
290
|
+
yield request
|
|
291
|
+
|
|
292
|
+
async for response in implementation.rpc_stream(requests()):
|
|
293
|
+
await call.send(response.SerializeToString(deterministic=True))
|
|
294
|
+
|
|
295
|
+
registry.register(service, "RpcStream", rpc_stream_handler)
|
|
296
|
+
|
|
297
|
+
async def do_nothing_handler(call: Call) -> None:
|
|
298
|
+
first = await call.receive()
|
|
299
|
+
if first is None:
|
|
300
|
+
raise CallProtocolError("missing initial request")
|
|
301
|
+
request = _google_protobuf_empty_pb2.Empty()
|
|
302
|
+
request.ParseFromString(first)
|
|
303
|
+
response = await implementation.do_nothing(request)
|
|
304
|
+
await call.send(response.SerializeToString(deterministic=True))
|
|
305
|
+
|
|
306
|
+
registry.register(service, "DoNothing", do_nothing_handler)
|