starpc 0.49.18 → 0.50.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/README.md +1 -3
- package/cmd/protoc-gen-es-starpc/typescript.ts +11 -6
- package/dist/cmd/protoc-gen-es-starpc/typescript.js +6 -5
- package/dist/echo/echo.pb.d.ts +1 -1
- package/dist/echo/echo.pb.js +3 -3
- package/dist/integration/cross-language/ts-client.js +84 -11
- package/dist/integration/cross-language/ts-server.js +100 -4
- package/dist/mock/index.d.ts +2 -2
- package/dist/mock/index.js +2 -2
- package/dist/mock/mock.pb.d.ts +1 -1
- package/dist/mock/mock.pb.js +3 -3
- package/dist/rpcstream/receipt.test.d.ts +1 -0
- package/dist/rpcstream/receipt.test.js +41 -0
- package/dist/rpcstream/rpcstream.pb.d.ts +1 -1
- package/dist/rpcstream/rpcstream.pb.js +14 -8
- package/dist/srpc/call-receipt.d.ts +17 -0
- package/dist/srpc/call-receipt.js +106 -0
- package/dist/srpc/call-receipt.test.d.ts +1 -0
- package/dist/srpc/call-receipt.test.js +375 -0
- package/dist/srpc/client.d.ts +3 -1
- package/dist/srpc/client.js +20 -0
- package/dist/srpc/common-rpc.d.ts +13 -3
- package/dist/srpc/common-rpc.js +87 -10
- package/dist/srpc/handler.d.ts +2 -1
- package/dist/srpc/index.d.ts +4 -0
- package/dist/srpc/index.js +3 -0
- package/dist/srpc/invoker.d.ts +2 -1
- package/dist/srpc/invoker.js +2 -2
- package/dist/srpc/rpcproto.pb.d.ts +45 -1
- package/dist/srpc/rpcproto.pb.js +60 -7
- package/dist/srpc/server-invocation.d.ts +17 -0
- package/dist/srpc/server-invocation.js +37 -0
- package/dist/srpc/server-rpc.js +3 -1
- package/echo/echo.pb.go +1 -1
- package/echo/echo.pb.ts +6 -5
- package/echo/echo_srpc.pb.cpp +1 -1
- package/echo/echo_srpc.pb.go +1 -1
- package/echo/echo_srpc.pb.hpp +1 -1
- package/echo/echo_srpc.pb.rs +1 -1
- package/go.mod +13 -12
- package/go.sum +24 -24
- package/integration/cross-language/go-client/main.go +137 -5
- package/integration/cross-language/go-server/fixture-owner_test.go +127 -0
- package/integration/cross-language/go-server/main.go +169 -4
- package/integration/cross-language/run.bash +117 -13
- package/integration/cross-language/ts-client.ts +94 -13
- package/integration/cross-language/ts-server.ts +115 -7
- package/mock/index.ts +2 -2
- package/mock/mock.pb.go +1 -1
- package/mock/mock.pb.ts +6 -5
- package/mock/mock_srpc.pb.cpp +1 -1
- package/mock/mock_srpc.pb.go +1 -1
- package/mock/mock_srpc.pb.hpp +1 -1
- package/mock/mock_srpc.pb.rs +1 -1
- package/package.json +19 -26
- package/srpc/accept.go +1 -1
- package/srpc/call-receipt-e2e_test.go +111 -0
- package/srpc/call-receipt.go +112 -0
- package/srpc/call-receipt.test.ts +441 -0
- package/srpc/call-receipt.ts +131 -0
- package/srpc/call-receipt_test.go +536 -0
- package/srpc/client-rpc.go +1 -8
- package/srpc/client.ts +29 -2
- package/srpc/common-rpc.go +114 -29
- package/srpc/common-rpc.ts +104 -13
- package/srpc/handler.ts +2 -0
- package/srpc/index.ts +4 -0
- package/srpc/invoker.ts +10 -5
- package/srpc/msg-stream.go +8 -0
- package/srpc/muxed-conn.go +9 -4
- package/srpc/muxed-conn_test.go +79 -0
- package/srpc/muxed-yamux.go +1 -1
- package/srpc/rpcproto.pb.cc +15 -4
- package/srpc/rpcproto.pb.go +97 -1
- package/srpc/rpcproto.pb.h +59 -0
- package/srpc/rpcproto.pb.rs +45 -0
- package/srpc/rpcproto.pb.ts +90 -27
- package/srpc/rpcproto.proto +16 -0
- package/srpc/schema-ownership_test.go +115 -0
- package/srpc/server-invocation.go +40 -0
- package/srpc/server-invocation.ts +76 -0
- package/srpc/server-rpc.go +1 -1
- package/srpc/server-rpc.ts +6 -2
- package/srpc/stream-yamux.go +1 -1
- package/srpc/stream.go +20 -0
- package/srpc/websocket.go +1 -1
package/dist/srpc/invoker.js
CHANGED
|
@@ -6,7 +6,7 @@ import { MethodKind } from '@aptre/protobuf-es-lite';
|
|
|
6
6
|
// createInvokeFn builds an InvokeFn from a method definition and a function prototype.
|
|
7
7
|
export function createInvokeFn(methodInfo, methodProto) {
|
|
8
8
|
const requestDecode = buildDecodeMessageTransform(methodInfo.I);
|
|
9
|
-
return async (dataSource, dataSink) => {
|
|
9
|
+
return async (dataSource, dataSink, invocation) => {
|
|
10
10
|
// responseSink is a Sink for response messages.
|
|
11
11
|
const responseSink = pushable({
|
|
12
12
|
objectMode: true,
|
|
@@ -34,7 +34,7 @@ export function createInvokeFn(methodInfo, methodProto) {
|
|
|
34
34
|
}
|
|
35
35
|
// Call the implementation.
|
|
36
36
|
try {
|
|
37
|
-
const responseObj = methodProto(requestArg);
|
|
37
|
+
const responseObj = methodProto(requestArg, invocation);
|
|
38
38
|
if (!responseObj) {
|
|
39
39
|
throw new Error('return value was undefined');
|
|
40
40
|
}
|
|
@@ -1,5 +1,49 @@
|
|
|
1
|
-
import type { MessageType } from '@aptre/protobuf-es-lite';
|
|
1
|
+
import type { MessageType } from '@aptre/protobuf-es-lite/message';
|
|
2
2
|
export declare const protobufPackage = "srpc";
|
|
3
|
+
/**
|
|
4
|
+
* TerminalKind is the terminal state of a held unary invocation.
|
|
5
|
+
*
|
|
6
|
+
* @generated from enum srpc.TerminalKind
|
|
7
|
+
*/
|
|
8
|
+
export declare enum TerminalKind {
|
|
9
|
+
/**
|
|
10
|
+
* TERMINAL_KIND_UNSPECIFIED is not a valid terminal state.
|
|
11
|
+
*
|
|
12
|
+
* @generated from enum value: TERMINAL_KIND_UNSPECIFIED = 0;
|
|
13
|
+
*/
|
|
14
|
+
UNSPECIFIED = 0,
|
|
15
|
+
/**
|
|
16
|
+
* TERMINAL_KIND_COMMITTED identifies an explicit remote CallData completion.
|
|
17
|
+
*
|
|
18
|
+
* @generated from enum value: TERMINAL_KIND_COMMITTED = 1;
|
|
19
|
+
*/
|
|
20
|
+
COMMITTED = 1,
|
|
21
|
+
/**
|
|
22
|
+
* TERMINAL_KIND_CANCELED identifies a remote CallCancel packet.
|
|
23
|
+
*
|
|
24
|
+
* @generated from enum value: TERMINAL_KIND_CANCELED = 2;
|
|
25
|
+
*/
|
|
26
|
+
CANCELED = 2,
|
|
27
|
+
/**
|
|
28
|
+
* TERMINAL_KIND_TRANSPORT_LOST identifies a remote error or transport failure.
|
|
29
|
+
*
|
|
30
|
+
* @generated from enum value: TERMINAL_KIND_TRANSPORT_LOST = 3;
|
|
31
|
+
*/
|
|
32
|
+
TRANSPORT_LOST = 3,
|
|
33
|
+
/**
|
|
34
|
+
* TERMINAL_KIND_CLOSED identifies a bare remote close without completion.
|
|
35
|
+
*
|
|
36
|
+
* @generated from enum value: TERMINAL_KIND_CLOSED = 4;
|
|
37
|
+
*/
|
|
38
|
+
CLOSED = 4,
|
|
39
|
+
/**
|
|
40
|
+
* TERMINAL_KIND_ABANDONED identifies owner-context expiry without a remote terminal.
|
|
41
|
+
*
|
|
42
|
+
* @generated from enum value: TERMINAL_KIND_ABANDONED = 5;
|
|
43
|
+
*/
|
|
44
|
+
ABANDONED = 5
|
|
45
|
+
}
|
|
46
|
+
export declare const TerminalKind_Enum: import("@aptre/protobuf-es-lite/enum").EnumType;
|
|
3
47
|
/**
|
|
4
48
|
* CallStart requests starting a new RPC call.
|
|
5
49
|
*
|
package/dist/srpc/rpcproto.pb.js
CHANGED
|
@@ -1,10 +1,64 @@
|
|
|
1
1
|
// @generated by protoc-gen-es-lite unknown with parameter "target=ts,ts_nocheck=false"
|
|
2
2
|
// @generated from file github.com/aperturerobotics/starpc/srpc/rpcproto.proto (package srpc, syntax proto3)
|
|
3
3
|
/* eslint-disable */
|
|
4
|
-
import {
|
|
4
|
+
import { createEnumType } from '@aptre/protobuf-es-lite/enum';
|
|
5
|
+
import { createMessageType } from '@aptre/protobuf-es-lite/message';
|
|
6
|
+
import { ScalarType } from '@aptre/protobuf-es-lite/scalar';
|
|
5
7
|
export const protobufPackage = 'srpc';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* TerminalKind is the terminal state of a held unary invocation.
|
|
10
|
+
*
|
|
11
|
+
* @generated from enum srpc.TerminalKind
|
|
12
|
+
*/
|
|
13
|
+
export var TerminalKind;
|
|
14
|
+
(function (TerminalKind) {
|
|
15
|
+
/**
|
|
16
|
+
* TERMINAL_KIND_UNSPECIFIED is not a valid terminal state.
|
|
17
|
+
*
|
|
18
|
+
* @generated from enum value: TERMINAL_KIND_UNSPECIFIED = 0;
|
|
19
|
+
*/
|
|
20
|
+
TerminalKind[TerminalKind["UNSPECIFIED"] = 0] = "UNSPECIFIED";
|
|
21
|
+
/**
|
|
22
|
+
* TERMINAL_KIND_COMMITTED identifies an explicit remote CallData completion.
|
|
23
|
+
*
|
|
24
|
+
* @generated from enum value: TERMINAL_KIND_COMMITTED = 1;
|
|
25
|
+
*/
|
|
26
|
+
TerminalKind[TerminalKind["COMMITTED"] = 1] = "COMMITTED";
|
|
27
|
+
/**
|
|
28
|
+
* TERMINAL_KIND_CANCELED identifies a remote CallCancel packet.
|
|
29
|
+
*
|
|
30
|
+
* @generated from enum value: TERMINAL_KIND_CANCELED = 2;
|
|
31
|
+
*/
|
|
32
|
+
TerminalKind[TerminalKind["CANCELED"] = 2] = "CANCELED";
|
|
33
|
+
/**
|
|
34
|
+
* TERMINAL_KIND_TRANSPORT_LOST identifies a remote error or transport failure.
|
|
35
|
+
*
|
|
36
|
+
* @generated from enum value: TERMINAL_KIND_TRANSPORT_LOST = 3;
|
|
37
|
+
*/
|
|
38
|
+
TerminalKind[TerminalKind["TRANSPORT_LOST"] = 3] = "TRANSPORT_LOST";
|
|
39
|
+
/**
|
|
40
|
+
* TERMINAL_KIND_CLOSED identifies a bare remote close without completion.
|
|
41
|
+
*
|
|
42
|
+
* @generated from enum value: TERMINAL_KIND_CLOSED = 4;
|
|
43
|
+
*/
|
|
44
|
+
TerminalKind[TerminalKind["CLOSED"] = 4] = "CLOSED";
|
|
45
|
+
/**
|
|
46
|
+
* TERMINAL_KIND_ABANDONED identifies owner-context expiry without a remote terminal.
|
|
47
|
+
*
|
|
48
|
+
* @generated from enum value: TERMINAL_KIND_ABANDONED = 5;
|
|
49
|
+
*/
|
|
50
|
+
TerminalKind[TerminalKind["ABANDONED"] = 5] = "ABANDONED";
|
|
51
|
+
})(TerminalKind || (TerminalKind = {}));
|
|
52
|
+
export const TerminalKind_Enum = /* @__PURE__ */ createEnumType('srpc.TerminalKind', [
|
|
53
|
+
[0, 'TERMINAL_KIND_UNSPECIFIED'],
|
|
54
|
+
[1, 'TERMINAL_KIND_COMMITTED'],
|
|
55
|
+
[2, 'TERMINAL_KIND_CANCELED'],
|
|
56
|
+
[3, 'TERMINAL_KIND_TRANSPORT_LOST'],
|
|
57
|
+
[4, 'TERMINAL_KIND_CLOSED'],
|
|
58
|
+
[5, 'TERMINAL_KIND_ABANDONED'],
|
|
59
|
+
]);
|
|
60
|
+
export const CallStart =
|
|
61
|
+
/* @__PURE__ */ createMessageType({
|
|
8
62
|
typeName: 'srpc.CallStart',
|
|
9
63
|
fields: [
|
|
10
64
|
{ no: 1, name: 'rpc_service', kind: 'scalar', T: ScalarType.STRING },
|
|
@@ -14,8 +68,8 @@ export const CallStart = createMessageType({
|
|
|
14
68
|
],
|
|
15
69
|
packedByDefault: true,
|
|
16
70
|
});
|
|
17
|
-
|
|
18
|
-
|
|
71
|
+
export const CallData =
|
|
72
|
+
/* @__PURE__ */ createMessageType({
|
|
19
73
|
typeName: 'srpc.CallData',
|
|
20
74
|
fields: [
|
|
21
75
|
{ no: 1, name: 'data', kind: 'scalar', T: ScalarType.BYTES },
|
|
@@ -25,8 +79,7 @@ export const CallData = createMessageType({
|
|
|
25
79
|
],
|
|
26
80
|
packedByDefault: true,
|
|
27
81
|
});
|
|
28
|
-
|
|
29
|
-
export const Packet = createMessageType({
|
|
82
|
+
export const Packet = /* @__PURE__ */ createMessageType({
|
|
30
83
|
typeName: 'srpc.Packet',
|
|
31
84
|
fields: [
|
|
32
85
|
{
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TerminalKind } from './rpcproto.pb.js';
|
|
2
|
+
export declare class ServerInvocation implements AbortSignal {
|
|
3
|
+
readonly signal: AbortSignal;
|
|
4
|
+
private readonly waitFn;
|
|
5
|
+
constructor(signal: AbortSignal, waitFn: (ownerSignal: AbortSignal) => Promise<TerminalKind>);
|
|
6
|
+
get aborted(): boolean;
|
|
7
|
+
get onabort(): typeof this.signal.onabort;
|
|
8
|
+
set onabort(value: typeof this.signal.onabort);
|
|
9
|
+
get reason(): any;
|
|
10
|
+
throwIfAborted(): void;
|
|
11
|
+
addEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
12
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
13
|
+
removeEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
14
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
15
|
+
dispatchEvent(event: Event): boolean;
|
|
16
|
+
waitTerminal(ownerSignal: AbortSignal): Promise<TerminalKind>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ServerInvocation exposes the invocation signal and terminal wait.
|
|
2
|
+
export class ServerInvocation {
|
|
3
|
+
signal;
|
|
4
|
+
waitFn;
|
|
5
|
+
constructor(signal, waitFn) {
|
|
6
|
+
this.signal = signal;
|
|
7
|
+
this.waitFn = waitFn;
|
|
8
|
+
}
|
|
9
|
+
get aborted() {
|
|
10
|
+
return this.signal.aborted;
|
|
11
|
+
}
|
|
12
|
+
get onabort() {
|
|
13
|
+
return this.signal.onabort;
|
|
14
|
+
}
|
|
15
|
+
set onabort(value) {
|
|
16
|
+
this.signal.onabort = value;
|
|
17
|
+
}
|
|
18
|
+
get reason() {
|
|
19
|
+
return this.signal.reason;
|
|
20
|
+
}
|
|
21
|
+
throwIfAborted() {
|
|
22
|
+
this.signal.throwIfAborted();
|
|
23
|
+
}
|
|
24
|
+
addEventListener(type, listener, options) {
|
|
25
|
+
this.signal.addEventListener(type, listener, options);
|
|
26
|
+
}
|
|
27
|
+
removeEventListener(type, listener, options) {
|
|
28
|
+
this.signal.removeEventListener(type, listener, options);
|
|
29
|
+
}
|
|
30
|
+
dispatchEvent(event) {
|
|
31
|
+
return this.signal.dispatchEvent(event);
|
|
32
|
+
}
|
|
33
|
+
// waitTerminal waits for a remote terminal or owner-signal cancellation.
|
|
34
|
+
waitTerminal(ownerSignal) {
|
|
35
|
+
return this.waitFn(ownerSignal);
|
|
36
|
+
}
|
|
37
|
+
}
|
package/dist/srpc/server-rpc.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CommonRPC } from './common-rpc.js';
|
|
2
|
+
import { ServerInvocation } from './server-invocation.js';
|
|
2
3
|
// ServerRPC is an ongoing RPC from the server side.
|
|
3
4
|
export class ServerRPC extends CommonRPC {
|
|
4
5
|
// lookupMethod looks up the incoming RPC methods.
|
|
@@ -37,8 +38,9 @@ export class ServerRPC extends CommonRPC {
|
|
|
37
38
|
// invokeRPC starts invoking the RPC handler.
|
|
38
39
|
async invokeRPC(invokeFn) {
|
|
39
40
|
const dataSink = this._createDataSink();
|
|
41
|
+
const invocation = new ServerInvocation(this.invocationSignal, (ownerSignal) => this.waitTerminal(ownerSignal));
|
|
40
42
|
try {
|
|
41
|
-
await invokeFn(this.rpcDataSource, dataSink);
|
|
43
|
+
await invokeFn(this.rpcDataSource, dataSink, invocation);
|
|
42
44
|
}
|
|
43
45
|
catch (err) {
|
|
44
46
|
this.close(err);
|
package/echo/echo.pb.go
CHANGED
package/echo/echo.pb.ts
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// @generated from file github.com/aperturerobotics/starpc/echo/echo.proto (package echo, syntax proto3)
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
|
|
5
|
-
import type { MessageType
|
|
6
|
-
import { createMessageType
|
|
5
|
+
import type { MessageType } from '@aptre/protobuf-es-lite/message'
|
|
6
|
+
import { createMessageType } from '@aptre/protobuf-es-lite/message'
|
|
7
|
+
import { ScalarType } from '@aptre/protobuf-es-lite/scalar'
|
|
8
|
+
import type { PartialFieldInfo } from '@aptre/protobuf-es-lite/field'
|
|
7
9
|
|
|
8
10
|
export const protobufPackage = 'echo'
|
|
9
11
|
|
|
@@ -19,11 +21,10 @@ export interface EchoMsg {
|
|
|
19
21
|
body?: string
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
export const EchoMsg: MessageType<EchoMsg> = createMessageType({
|
|
24
|
+
export const EchoMsg: MessageType<EchoMsg> = /* @__PURE__ */ createMessageType({
|
|
24
25
|
typeName: 'echo.EchoMsg',
|
|
25
26
|
fields: [
|
|
26
27
|
{ no: 1, name: 'body', kind: 'scalar', T: ScalarType.STRING },
|
|
27
|
-
]
|
|
28
|
+
] satisfies readonly PartialFieldInfo[],
|
|
28
29
|
packedByDefault: true,
|
|
29
30
|
})
|
package/echo/echo_srpc.pb.cpp
CHANGED
package/echo/echo_srpc.pb.go
CHANGED
package/echo/echo_srpc.pb.hpp
CHANGED
package/echo/echo_srpc.pb.rs
CHANGED
package/go.mod
CHANGED
|
@@ -3,31 +3,32 @@ module github.com/aperturerobotics/starpc
|
|
|
3
3
|
go 1.25.0
|
|
4
4
|
|
|
5
5
|
require (
|
|
6
|
-
github.com/aperturerobotics/common v0.
|
|
7
|
-
github.com/aperturerobotics/protobuf-go-lite v0.
|
|
8
|
-
github.com/aperturerobotics/util v1.34.
|
|
6
|
+
github.com/aperturerobotics/common v0.34.4 // latest
|
|
7
|
+
github.com/aperturerobotics/protobuf-go-lite v0.16.0 // latest
|
|
8
|
+
github.com/aperturerobotics/util v1.34.9 // latest
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
require (
|
|
12
12
|
github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017 // aperture-2
|
|
13
13
|
github.com/aperturerobotics/cli v1.1.0 // indirect
|
|
14
|
-
github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-
|
|
15
|
-
github.com/aperturerobotics/go-protoc-wasi v0.0.0-
|
|
16
|
-
github.com/aperturerobotics/go-websocket v1.8.15-0.
|
|
17
|
-
github.com/aperturerobotics/json-iterator-lite v1.
|
|
14
|
+
github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b // indirect
|
|
15
|
+
github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260712054757-d8078c296c17 // indirect
|
|
16
|
+
github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1 // master
|
|
17
|
+
github.com/aperturerobotics/json-iterator-lite v1.1.0 // indirect
|
|
18
18
|
github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4 // wasi
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
require (
|
|
22
|
-
github.com/libp2p/go-yamux/v4 v4.0.2 // latest
|
|
23
22
|
github.com/pkg/errors v0.9.1 // latest
|
|
24
|
-
github.com/sirupsen/logrus v1.9.5-0.
|
|
23
|
+
github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb // latest
|
|
25
24
|
)
|
|
26
25
|
|
|
26
|
+
require github.com/libp2p/go-yamux/v5 v5.1.0
|
|
27
|
+
|
|
27
28
|
require (
|
|
28
29
|
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
|
29
|
-
github.com/tetratelabs/wazero v1.
|
|
30
|
+
github.com/tetratelabs/wazero v1.12.0 // indirect
|
|
30
31
|
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
|
|
31
|
-
golang.org/x/mod v0.
|
|
32
|
-
golang.org/x/sys v0.
|
|
32
|
+
golang.org/x/mod v0.38.0 // indirect
|
|
33
|
+
golang.org/x/sys v0.47.0 // indirect
|
|
33
34
|
)
|
package/go.sum
CHANGED
|
@@ -2,46 +2,46 @@ github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017 h1:3U7
|
|
|
2
2
|
github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017/go.mod h1:lNSJTKECIUFAnfeSqy01kXYTYe1BHubW7198jNX3nEw=
|
|
3
3
|
github.com/aperturerobotics/cli v1.1.0 h1:7a+YRC+EY3npAnTzhHV5gLCiw91KS0Ts3XwLILGOsT8=
|
|
4
4
|
github.com/aperturerobotics/cli v1.1.0/go.mod h1:M7BFP9wow5ytTzMyJQOOO991fGfsUqdTI7gGEsHfTQ8=
|
|
5
|
-
github.com/aperturerobotics/common v0.
|
|
6
|
-
github.com/aperturerobotics/common v0.
|
|
7
|
-
github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-
|
|
8
|
-
github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-
|
|
9
|
-
github.com/aperturerobotics/go-protoc-wasi v0.0.0-
|
|
10
|
-
github.com/aperturerobotics/go-protoc-wasi v0.0.0-
|
|
11
|
-
github.com/aperturerobotics/go-websocket v1.8.15-0.
|
|
12
|
-
github.com/aperturerobotics/go-websocket v1.8.15-0.
|
|
13
|
-
github.com/aperturerobotics/json-iterator-lite v1.
|
|
14
|
-
github.com/aperturerobotics/json-iterator-lite v1.
|
|
5
|
+
github.com/aperturerobotics/common v0.34.4 h1:RQTOm6LxEnucXkED/kruhKKAOL6tbaPzMgfHPKaES4k=
|
|
6
|
+
github.com/aperturerobotics/common v0.34.4/go.mod h1:xnb1VBRs3x2o1PaKg0OlP7SqDaC9Hmrmt9xH85rOS+A=
|
|
7
|
+
github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b h1:MMk+AbWPCMfqc2Lm2bJl8lCCsuvlM2+C0CP10fpE3bc=
|
|
8
|
+
github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b/go.mod h1:OBb/beWmr/pDIZAUfi86j/4tBh2v5ctTxKMqSnh9c/4=
|
|
9
|
+
github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260712054757-d8078c296c17 h1:WT1YmZjJf8fUF1zKbeNNKXFA+t8Wtbr8AVMAmdKcrUU=
|
|
10
|
+
github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260712054757-d8078c296c17/go.mod h1:vEq8i7EKb32+KXGtIEZjjhNns+BdsL2dUMw4uhy3578=
|
|
11
|
+
github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1 h1:q2qkdNOrnhAFf6B7TBeUoAYstYWxPvozN+3vJi2jgp0=
|
|
12
|
+
github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1/go.mod h1:9KnSGuqxSXbdB/Oi0I6vvfPLkclfJwMGAQaDDGVgGow=
|
|
13
|
+
github.com/aperturerobotics/json-iterator-lite v1.1.0 h1:ZLLqHhHTKYlmCAP873ras2e/yVU/THtwC+ji3tXLMMg=
|
|
14
|
+
github.com/aperturerobotics/json-iterator-lite v1.1.0/go.mod h1:SvGGBv3OVxUyqO0ZxA/nvs6z3cg7NIbZ64TnbV2OISo=
|
|
15
15
|
github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4 h1:4Dy3BAHh2kgVdHAqtlwcFsgY0kAwUe2m3rfFcaGwGQg=
|
|
16
16
|
github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4/go.mod h1:tMgO7y6SJo/d9ZcvrpNqIQtdYT9de+QmYaHOZ4KnhOg=
|
|
17
|
-
github.com/aperturerobotics/protobuf-go-lite v0.
|
|
18
|
-
github.com/aperturerobotics/protobuf-go-lite v0.
|
|
19
|
-
github.com/aperturerobotics/util v1.34.
|
|
20
|
-
github.com/aperturerobotics/util v1.34.
|
|
17
|
+
github.com/aperturerobotics/protobuf-go-lite v0.16.0 h1:McGR0jrc15ZkH8HUpAARDOtazjwqr+uYXVHrrR59K28=
|
|
18
|
+
github.com/aperturerobotics/protobuf-go-lite v0.16.0/go.mod h1:3Ay/E7iaw2KWLirK3+dDdNJZHK0hu8Y1/kKeYeUa+8s=
|
|
19
|
+
github.com/aperturerobotics/util v1.34.9 h1:Eyhu1Citt+od7jKIb+Q92h/CEujWCFsvdvJavQeoRjM=
|
|
20
|
+
github.com/aperturerobotics/util v1.34.9/go.mod h1:GxjGkYQNEj8xvLFz+T8ifqANtK5cMesOlCxh50htvBI=
|
|
21
21
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
22
22
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
23
23
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
|
24
24
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
|
25
25
|
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
|
26
26
|
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
|
27
|
-
github.com/libp2p/go-yamux/
|
|
28
|
-
github.com/libp2p/go-yamux/
|
|
27
|
+
github.com/libp2p/go-yamux/v5 v5.1.0 h1:8Qlxj4E9JGJAQVW6+uj2o7mqkqsIVlSUGmTWhlXzoHE=
|
|
28
|
+
github.com/libp2p/go-yamux/v5 v5.1.0/go.mod h1:tgIQ07ObtRR/I0IWsFOyQIL9/dR5UXgc2s8xKmNZv1o=
|
|
29
29
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
30
30
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
31
31
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
32
32
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
33
|
-
github.com/sirupsen/logrus v1.9.5-0.
|
|
34
|
-
github.com/sirupsen/logrus v1.9.5-0.
|
|
33
|
+
github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb h1:+C8W2sTMIRbihe5hQH6JuT2mi3m/QgdGf0YdFyx2azA=
|
|
34
|
+
github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb/go.mod h1:FXZFonkDAnFozmO+5hGAFvB0Yg9/j2SIhA/QuIkP180=
|
|
35
35
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
|
36
36
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
|
37
|
-
github.com/tetratelabs/wazero v1.
|
|
38
|
-
github.com/tetratelabs/wazero v1.
|
|
37
|
+
github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU=
|
|
38
|
+
github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0=
|
|
39
39
|
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg=
|
|
40
40
|
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
|
41
|
-
golang.org/x/mod v0.
|
|
42
|
-
golang.org/x/mod v0.
|
|
43
|
-
golang.org/x/sys v0.
|
|
44
|
-
golang.org/x/sys v0.
|
|
41
|
+
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
|
|
42
|
+
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
|
|
43
|
+
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
|
44
|
+
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
|
45
45
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
|
46
46
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
|
47
47
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
@@ -2,6 +2,7 @@ package main
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
|
+
"errors"
|
|
5
6
|
"fmt"
|
|
6
7
|
"io"
|
|
7
8
|
"net"
|
|
@@ -14,14 +15,32 @@ import (
|
|
|
14
15
|
const bodyTxt = "hello world via starpc cross-language e2e test"
|
|
15
16
|
|
|
16
17
|
func main() {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
receiptMode := len(os.Args) > 1 && os.Args[1] == "receipt"
|
|
19
|
+
receiptCase := ""
|
|
20
|
+
addrIndex := 1
|
|
21
|
+
if receiptMode {
|
|
22
|
+
if len(os.Args) < 3 {
|
|
23
|
+
fmt.Fprintf(os.Stderr, "usage: go-client receipt <case> <addr>\n")
|
|
24
|
+
os.Exit(1)
|
|
25
|
+
}
|
|
26
|
+
receiptCase = os.Args[2]
|
|
27
|
+
addrIndex = 3
|
|
28
|
+
switch receiptCase {
|
|
29
|
+
case "commit", "abort", "loss", "bare-close":
|
|
30
|
+
default:
|
|
31
|
+
fmt.Fprintf(os.Stderr, "unknown receipt case: %s\n", receiptCase)
|
|
32
|
+
os.Exit(1)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if len(os.Args) <= addrIndex {
|
|
36
|
+
fmt.Fprintf(os.Stderr, "usage: go-client [receipt <case>] <addr>\n")
|
|
19
37
|
os.Exit(1)
|
|
20
38
|
}
|
|
21
|
-
addr := os.Args[
|
|
22
|
-
|
|
39
|
+
addr := os.Args[addrIndex]
|
|
40
|
+
var conn net.Conn
|
|
23
41
|
openStream := func(ctx context.Context, msgHandler srpc.PacketDataHandler, closeHandler srpc.CloseHandler) (srpc.PacketWriter, error) {
|
|
24
|
-
|
|
42
|
+
var err error
|
|
43
|
+
conn, err = net.Dial("tcp", addr) //nolint:gosec
|
|
25
44
|
if err != nil {
|
|
26
45
|
return nil, err
|
|
27
46
|
}
|
|
@@ -33,6 +52,14 @@ func main() {
|
|
|
33
52
|
client := srpc.NewClient(openStream)
|
|
34
53
|
echoClient := echo.NewSRPCEchoerClient(client)
|
|
35
54
|
ctx := context.Background()
|
|
55
|
+
if receiptMode {
|
|
56
|
+
if err := testReceipt(ctx, client, &conn, receiptCase); err != nil {
|
|
57
|
+
fmt.Fprintf(os.Stderr, "receipt test failed: %v\n", err)
|
|
58
|
+
os.Exit(1)
|
|
59
|
+
}
|
|
60
|
+
fmt.Println("All tests passed.")
|
|
61
|
+
return
|
|
62
|
+
}
|
|
36
63
|
|
|
37
64
|
if err := testUnary(ctx, echoClient); err != nil {
|
|
38
65
|
fmt.Fprintf(os.Stderr, "unary test failed: %v\n", err)
|
|
@@ -70,6 +97,79 @@ func testUnary(ctx context.Context, client echo.SRPCEchoerClient) error {
|
|
|
70
97
|
return nil
|
|
71
98
|
}
|
|
72
99
|
|
|
100
|
+
func testReceipt(
|
|
101
|
+
ctx context.Context,
|
|
102
|
+
client srpc.Client,
|
|
103
|
+
conn *net.Conn,
|
|
104
|
+
receiptCase string,
|
|
105
|
+
) error {
|
|
106
|
+
fmt.Printf("Testing held unary receipt (%s)...\n", receiptCase)
|
|
107
|
+
out := new(echo.EchoMsg)
|
|
108
|
+
receipt, err := srpc.ExecCallReceipt(
|
|
109
|
+
ctx, client, echo.SRPCEchoerServiceID, "Echo",
|
|
110
|
+
&echo.EchoMsg{Body: bodyTxt}, out,
|
|
111
|
+
)
|
|
112
|
+
if err != nil {
|
|
113
|
+
return fmt.Errorf("receipt call: %w", err)
|
|
114
|
+
}
|
|
115
|
+
if out.GetBody() != bodyTxt {
|
|
116
|
+
return fmt.Errorf("expected %q got %q", bodyTxt, out.GetBody())
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
switch receiptCase {
|
|
120
|
+
case "commit":
|
|
121
|
+
if err := receipt.Commit(); err != nil {
|
|
122
|
+
return fmt.Errorf("receipt commit: %w", err)
|
|
123
|
+
}
|
|
124
|
+
case "abort":
|
|
125
|
+
if err := receipt.Abort(); err != nil {
|
|
126
|
+
return fmt.Errorf("receipt abort: %w", err)
|
|
127
|
+
}
|
|
128
|
+
case "loss":
|
|
129
|
+
if *conn == nil {
|
|
130
|
+
return errors.New("receipt connection is nil")
|
|
131
|
+
}
|
|
132
|
+
tcpConn, ok := (*conn).(*net.TCPConn)
|
|
133
|
+
if !ok {
|
|
134
|
+
return errors.New("receipt connection is not TCP")
|
|
135
|
+
}
|
|
136
|
+
if err := tcpConn.SetLinger(0); err != nil {
|
|
137
|
+
return fmt.Errorf("set receipt loss linger: %w", err)
|
|
138
|
+
}
|
|
139
|
+
if err := tcpConn.Close(); err != nil {
|
|
140
|
+
return fmt.Errorf("close lost connection: %w", err)
|
|
141
|
+
}
|
|
142
|
+
if err := receipt.Commit(); err == nil {
|
|
143
|
+
return errors.New("loss receipt commit unexpectedly succeeded")
|
|
144
|
+
}
|
|
145
|
+
case "bare-close":
|
|
146
|
+
if *conn == nil {
|
|
147
|
+
return errors.New("receipt connection is nil")
|
|
148
|
+
}
|
|
149
|
+
tcpConn, ok := (*conn).(*net.TCPConn)
|
|
150
|
+
if !ok {
|
|
151
|
+
return errors.New("receipt connection is not TCP")
|
|
152
|
+
}
|
|
153
|
+
if err := tcpConn.CloseWrite(); err != nil {
|
|
154
|
+
return fmt.Errorf("close receipt write side: %w", err)
|
|
155
|
+
}
|
|
156
|
+
if err := receipt.Commit(); err == nil {
|
|
157
|
+
return errors.New("bare-close receipt commit unexpectedly succeeded")
|
|
158
|
+
}
|
|
159
|
+
default:
|
|
160
|
+
return fmt.Errorf("unknown receipt case: %s", receiptCase)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if err := emitReceiptEvent(
|
|
164
|
+
fmt.Sprintf("CLIENT_RECEIPT_RESOLVED %s", receiptTerminalName(receiptCase)),
|
|
165
|
+
); err != nil {
|
|
166
|
+
return fmt.Errorf("record receipt resolution: %w", err)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fmt.Println(" PASSED")
|
|
170
|
+
return nil
|
|
171
|
+
}
|
|
172
|
+
|
|
73
173
|
func testServerStream(ctx context.Context, client echo.SRPCEchoerClient) error {
|
|
74
174
|
fmt.Println("Testing ServerStream RPC...")
|
|
75
175
|
strm, err := client.EchoServerStream(ctx, &echo.EchoMsg{Body: bodyTxt})
|
|
@@ -149,3 +249,35 @@ func testBidiStream(ctx context.Context, client echo.SRPCEchoerClient) error {
|
|
|
149
249
|
fmt.Println(" PASSED")
|
|
150
250
|
return nil
|
|
151
251
|
}
|
|
252
|
+
|
|
253
|
+
func receiptTerminalName(receiptCase string) string {
|
|
254
|
+
switch receiptCase {
|
|
255
|
+
case "commit":
|
|
256
|
+
return "committed"
|
|
257
|
+
case "abort":
|
|
258
|
+
return "canceled"
|
|
259
|
+
case "loss":
|
|
260
|
+
return "transportLost"
|
|
261
|
+
case "bare-close":
|
|
262
|
+
return "closed"
|
|
263
|
+
default:
|
|
264
|
+
return "unknown"
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
func emitReceiptEvent(line string) error {
|
|
269
|
+
fmt.Println(line)
|
|
270
|
+
fifo := os.Getenv("RECEIPT_EVENT_FIFO")
|
|
271
|
+
if fifo == "" {
|
|
272
|
+
return nil
|
|
273
|
+
}
|
|
274
|
+
file, err := os.OpenFile(fifo, os.O_WRONLY, 0) //nolint:gosec // FIFO path is created by the local integration runner.
|
|
275
|
+
if err != nil {
|
|
276
|
+
return err
|
|
277
|
+
}
|
|
278
|
+
if _, err := file.WriteString(line + "\n"); err != nil {
|
|
279
|
+
_ = file.Close()
|
|
280
|
+
return err
|
|
281
|
+
}
|
|
282
|
+
return file.Close()
|
|
283
|
+
}
|