@restatedev/restate-sdk 0.7.3-worker → 0.8.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/LICENSE +1 -1
- package/README.md +29 -51
- package/dist/clients/workflow_client.d.ts +77 -0
- package/dist/clients/workflow_client.d.ts.map +1 -0
- package/dist/clients/workflow_client.js +172 -0
- package/dist/clients/workflow_client.js.map +1 -0
- package/dist/connection/buffered_connection.js +44 -0
- package/dist/connection/buffered_connection.js.map +1 -0
- package/dist/connection/connection.js +13 -0
- package/dist/connection/connection.js.map +1 -0
- package/dist/connection/embedded_connection.js +59 -0
- package/dist/connection/embedded_connection.js.map +1 -0
- package/dist/connection/http_connection.js +203 -0
- package/dist/connection/http_connection.js.map +1 -0
- package/dist/connection/lambda_connection.js +58 -0
- package/dist/connection/lambda_connection.js.map +1 -0
- package/dist/{restate_context.d.ts → context.d.ts} +239 -170
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +113 -0
- package/dist/context.js.map +1 -0
- package/dist/{restate_context_impl.d.ts → context_impl.d.ts} +26 -30
- package/dist/context_impl.d.ts.map +1 -0
- package/dist/context_impl.js +439 -0
- package/dist/context_impl.js.map +1 -0
- package/dist/embedded/api.d.ts +2 -2
- package/dist/embedded/api.d.ts.map +1 -1
- package/dist/embedded/api.js +35 -0
- package/dist/embedded/api.js.map +1 -0
- package/dist/embedded/handler.d.ts +2 -2
- package/dist/embedded/handler.d.ts.map +1 -1
- package/dist/embedded/handler.js +26 -0
- package/dist/embedded/handler.js.map +1 -0
- package/dist/embedded/http2_remote.js +91 -0
- package/dist/embedded/http2_remote.js.map +1 -0
- package/dist/embedded/invocation.d.ts.map +1 -1
- package/dist/embedded/invocation.js +94 -0
- package/dist/embedded/invocation.js.map +1 -0
- package/dist/endpoint/endpoint_impl.d.ts +35 -0
- package/dist/endpoint/endpoint_impl.d.ts.map +1 -0
- package/dist/endpoint/endpoint_impl.js +405 -0
- package/dist/endpoint/endpoint_impl.js.map +1 -0
- package/dist/endpoint/http2_handler.d.ts +11 -0
- package/dist/endpoint/http2_handler.d.ts.map +1 -0
- package/dist/endpoint/http2_handler.js +119 -0
- package/dist/endpoint/http2_handler.js.map +1 -0
- package/dist/endpoint/lambda_handler.d.ts +15 -0
- package/dist/endpoint/lambda_handler.d.ts.map +1 -0
- package/dist/endpoint/lambda_handler.js +144 -0
- package/dist/endpoint/lambda_handler.js.map +1 -0
- package/dist/endpoint.d.ts +161 -0
- package/dist/endpoint.d.ts.map +1 -0
- package/dist/endpoint.js +22 -0
- package/dist/endpoint.js.map +1 -0
- package/dist/generated/dev/restate/events.js +371 -0
- package/dist/generated/dev/restate/events.js.map +1 -0
- package/dist/generated/dev/restate/ext.js +215 -0
- package/dist/generated/dev/restate/ext.js.map +1 -0
- package/dist/generated/google/protobuf/descriptor.js +6676 -0
- package/dist/generated/google/protobuf/descriptor.js.map +1 -0
- package/dist/generated/google/protobuf/empty.js +107 -0
- package/dist/generated/google/protobuf/empty.js.map +1 -0
- package/dist/generated/google/protobuf/struct.js +754 -0
- package/dist/generated/google/protobuf/struct.js.map +1 -0
- package/dist/generated/proto/discovery.js +364 -0
- package/dist/generated/proto/discovery.js.map +1 -0
- package/dist/generated/proto/dynrpc.js +668 -0
- package/dist/generated/proto/dynrpc.js.map +1 -0
- package/dist/generated/proto/javascript.d.ts +13 -0
- package/dist/generated/proto/javascript.d.ts.map +1 -1
- package/dist/generated/proto/javascript.js +416 -0
- package/dist/generated/proto/javascript.js.map +1 -0
- package/dist/generated/proto/protocol.d.ts +43 -0
- package/dist/generated/proto/protocol.d.ts.map +1 -1
- package/dist/generated/proto/protocol.js +2641 -0
- package/dist/generated/proto/protocol.js.map +1 -0
- package/dist/generated/proto/services.js +1535 -0
- package/dist/generated/proto/services.js.map +1 -0
- package/dist/generated/proto/test.js +321 -0
- package/dist/generated/proto/test.js.map +1 -0
- package/dist/invocation.d.ts +4 -1
- package/dist/invocation.d.ts.map +1 -1
- package/dist/invocation.js +157 -0
- package/dist/invocation.js.map +1 -0
- package/dist/io/decoder.d.ts +1 -0
- package/dist/io/decoder.d.ts.map +1 -1
- package/dist/io/decoder.js +140 -0
- package/dist/io/decoder.js.map +1 -0
- package/dist/io/encoder.d.ts +1 -2
- package/dist/io/encoder.d.ts.map +1 -1
- package/dist/io/encoder.js +68 -0
- package/dist/io/encoder.js.map +1 -0
- package/dist/journal.d.ts +13 -4
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +405 -0
- package/dist/journal.js.map +1 -0
- package/dist/local_state_store.d.ts +5 -3
- package/dist/local_state_store.d.ts.map +1 -1
- package/dist/local_state_store.js +82 -0
- package/dist/local_state_store.js.map +1 -0
- package/dist/logger.d.ts +19 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +90 -0
- package/dist/logger.js.map +1 -0
- package/dist/promise_combinator_tracker.d.ts +29 -0
- package/dist/promise_combinator_tracker.d.ts.map +1 -0
- package/dist/promise_combinator_tracker.js +128 -0
- package/dist/promise_combinator_tracker.js.map +1 -0
- package/dist/public_api.d.ts +5 -5
- package/dist/public_api.d.ts.map +1 -1
- package/dist/public_api.js +60 -0
- package/dist/public_api.js.map +1 -0
- package/dist/state_machine.d.ts +19 -12
- package/dist/state_machine.d.ts.map +1 -1
- package/dist/state_machine.js +437 -0
- package/dist/state_machine.js.map +1 -0
- package/dist/types/errors.d.ts +12 -3
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +273 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/grpc.d.ts +6 -4
- package/dist/types/grpc.d.ts.map +1 -1
- package/dist/types/grpc.js +81 -0
- package/dist/types/grpc.js.map +1 -0
- package/dist/types/protocol.d.ts +9 -5
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js +147 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/router.d.ts +8 -8
- package/dist/types/router.d.ts.map +1 -1
- package/dist/types/router.js +36 -0
- package/dist/types/router.js.map +1 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +138 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/{assumpsions.d.ts → assumptions.d.ts} +1 -1
- package/dist/utils/{assumpsions.d.ts.map → assumptions.d.ts.map} +1 -1
- package/dist/utils/assumptions.js +101 -0
- package/dist/utils/assumptions.js.map +1 -0
- package/dist/utils/message_logger.d.ts +28 -0
- package/dist/utils/message_logger.d.ts.map +1 -0
- package/dist/utils/message_logger.js +88 -0
- package/dist/utils/message_logger.js.map +1 -0
- package/dist/utils/promises.d.ts +15 -0
- package/dist/utils/promises.d.ts.map +1 -0
- package/dist/utils/promises.js +67 -0
- package/dist/utils/promises.js.map +1 -0
- package/dist/utils/public_utils.js +49 -0
- package/dist/utils/public_utils.js.map +1 -0
- package/dist/utils/rand.d.ts +1 -1
- package/dist/utils/rand.d.ts.map +1 -1
- package/dist/utils/rand.js +114 -0
- package/dist/utils/rand.js.map +1 -0
- package/dist/utils/utils.d.ts +1 -10
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +122 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/workflows/workflow.d.ts +101 -0
- package/dist/workflows/workflow.d.ts.map +1 -0
- package/dist/workflows/workflow.js +80 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/dist/workflows/workflow_state_service.d.ts +35 -0
- package/dist/workflows/workflow_state_service.d.ts.map +1 -0
- package/dist/workflows/workflow_state_service.js +201 -0
- package/dist/workflows/workflow_state_service.js.map +1 -0
- package/dist/workflows/workflow_wrapper_service.d.ts +10 -0
- package/dist/workflows/workflow_wrapper_service.d.ts.map +1 -0
- package/dist/workflows/workflow_wrapper_service.js +264 -0
- package/dist/workflows/workflow_wrapper_service.js.map +1 -0
- package/package.json +38 -39
- package/src/clients/workflow_client.ts +290 -0
- package/src/connection/buffered_connection.ts +47 -0
- package/src/connection/connection.ts +34 -0
- package/src/connection/embedded_connection.ts +62 -0
- package/src/connection/http_connection.ts +228 -0
- package/src/connection/lambda_connection.ts +69 -0
- package/src/context.ts +633 -0
- package/src/context_impl.ts +721 -0
- package/src/embedded/api.ts +57 -0
- package/src/embedded/handler.ts +36 -0
- package/src/embedded/http2_remote.ts +103 -0
- package/src/embedded/invocation.ts +126 -0
- package/src/endpoint/endpoint_impl.ts +623 -0
- package/src/endpoint/http2_handler.ts +151 -0
- package/src/endpoint/lambda_handler.ts +181 -0
- package/src/endpoint.ts +187 -0
- package/src/generated/dev/restate/events.ts +430 -0
- package/src/generated/dev/restate/ext.ts +238 -0
- package/src/generated/google/protobuf/descriptor.ts +7889 -0
- package/src/generated/google/protobuf/empty.ts +150 -0
- package/src/generated/google/protobuf/struct.ts +878 -0
- package/src/generated/proto/discovery.ts +423 -0
- package/src/generated/proto/dynrpc.ts +768 -0
- package/src/generated/proto/javascript.ts +488 -0
- package/src/generated/proto/protocol.ts +3091 -0
- package/src/generated/proto/services.ts +1834 -0
- package/src/generated/proto/test.ts +387 -0
- package/src/invocation.ts +212 -0
- package/src/io/decoder.ts +171 -0
- package/src/io/encoder.ts +72 -0
- package/src/journal.ts +537 -0
- package/src/local_state_store.ts +94 -0
- package/src/logger.ts +121 -0
- package/src/promise_combinator_tracker.ts +191 -0
- package/src/public_api.ts +53 -0
- package/src/state_machine.ts +635 -0
- package/src/types/errors.ts +297 -0
- package/src/types/grpc.ts +97 -0
- package/src/types/protocol.ts +201 -0
- package/src/types/router.ts +118 -0
- package/src/types/types.ts +160 -0
- package/src/utils/assumptions.ts +131 -0
- package/src/utils/message_logger.ts +112 -0
- package/src/utils/promises.ts +118 -0
- package/src/utils/public_utils.ts +91 -0
- package/src/utils/rand.ts +142 -0
- package/src/utils/utils.ts +178 -0
- package/src/workflows/workflow.ts +178 -0
- package/src/workflows/workflow_state_service.ts +299 -0
- package/src/workflows/workflow_wrapper_service.ts +314 -0
- package/dist/cloudflare_bundle.js +0 -27387
- package/dist/restate_context.d.ts.map +0 -1
- package/dist/restate_context_impl.d.ts.map +0 -1
- package/dist/server/base_restate_server.d.ts +0 -32
- package/dist/server/base_restate_server.d.ts.map +0 -1
- package/dist/server/restate_lambda_handler.d.ts +0 -104
- package/dist/server/restate_lambda_handler.d.ts.map +0 -1
- package/dist/server/restate_server.d.ts +0 -97
- package/dist/server/restate_server.d.ts.map +0 -1
- package/dist/utils/logger.d.ts +0 -60
- package/dist/utils/logger.d.ts.map +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
|
|
3
|
+
*
|
|
4
|
+
* This file is part of the Restate SDK for Node.js/TypeScript,
|
|
5
|
+
* which is released under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* You can find a copy of the license in file LICENSE in the root
|
|
8
|
+
* directory of this repository or package, or at
|
|
9
|
+
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Context } from "../context";
|
|
13
|
+
import { doInvoke } from "./invocation";
|
|
14
|
+
import { wrapHandler } from "./handler";
|
|
15
|
+
import crypto from "crypto";
|
|
16
|
+
import { RemoteContext } from "../generated/proto/services";
|
|
17
|
+
import { bufConnectRemoteContext } from "./http2_remote";
|
|
18
|
+
import { OutgoingHttpHeaders } from "http";
|
|
19
|
+
|
|
20
|
+
export type RestateConnectionOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* Additional headers attached to the requests sent to Restate.
|
|
23
|
+
*/
|
|
24
|
+
headers: OutgoingHttpHeaders;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type RestateInvocationOptions = {
|
|
28
|
+
/**
|
|
29
|
+
* Retention period for the response in seconds.
|
|
30
|
+
* After the invocation completes, the response will be persisted for the given duration.
|
|
31
|
+
* Afterward, the system will clean up the response and treats any subsequent invocation with same operation_id as new.
|
|
32
|
+
*
|
|
33
|
+
* If not set, 30 minutes will be used as retention period.
|
|
34
|
+
*/
|
|
35
|
+
retain?: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const connection = (
|
|
39
|
+
address: string,
|
|
40
|
+
opt?: RestateConnectionOptions
|
|
41
|
+
): RestateConnection =>
|
|
42
|
+
new RestateConnection(bufConnectRemoteContext(address, opt));
|
|
43
|
+
|
|
44
|
+
export class RestateConnection {
|
|
45
|
+
constructor(private readonly remote: RemoteContext) {}
|
|
46
|
+
|
|
47
|
+
public invoke<I, O>(
|
|
48
|
+
id: string,
|
|
49
|
+
input: I,
|
|
50
|
+
handler: (ctx: Context, input: I) => Promise<O>,
|
|
51
|
+
opt?: RestateInvocationOptions
|
|
52
|
+
): Promise<O> {
|
|
53
|
+
const method = wrapHandler(handler);
|
|
54
|
+
const streamId = crypto.randomUUID();
|
|
55
|
+
return doInvoke<I, O>(this.remote, id, streamId, input, method, opt);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
|
|
3
|
+
*
|
|
4
|
+
* This file is part of the Restate SDK for Node.js/TypeScript,
|
|
5
|
+
* which is released under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* You can find a copy of the license in file LICENSE in the root
|
|
8
|
+
* directory of this repository or package, or at
|
|
9
|
+
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Context, useContext } from "../context";
|
|
13
|
+
import { GrpcServiceMethod, HostedGrpcServiceMethod } from "../types/grpc";
|
|
14
|
+
|
|
15
|
+
export function wrapHandler<I, O>(
|
|
16
|
+
handler: (ctx: Context, input: I) => Promise<O>
|
|
17
|
+
): HostedGrpcServiceMethod<I, O> {
|
|
18
|
+
const localMethod = (instance: unknown, input: I): Promise<O> => {
|
|
19
|
+
return handler(useContext(instance), input);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const encoder = (output: O): Uint8Array =>
|
|
23
|
+
Buffer.from(JSON.stringify(output));
|
|
24
|
+
const decoder = (buf: Uint8Array): I => JSON.parse(buf.toString());
|
|
25
|
+
|
|
26
|
+
const method = new GrpcServiceMethod<I, O>(
|
|
27
|
+
"",
|
|
28
|
+
"",
|
|
29
|
+
false,
|
|
30
|
+
localMethod,
|
|
31
|
+
decoder,
|
|
32
|
+
encoder
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return new HostedGrpcServiceMethod<I, O>({}, "", "", method);
|
|
36
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
|
|
3
|
+
*
|
|
4
|
+
* This file is part of the Restate SDK for Node.js/TypeScript,
|
|
5
|
+
* which is released under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* You can find a copy of the license in file LICENSE in the root
|
|
8
|
+
* directory of this repository or package, or at
|
|
9
|
+
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import http2 from "node:http2";
|
|
13
|
+
import { once } from "events";
|
|
14
|
+
import {
|
|
15
|
+
RemoteContext,
|
|
16
|
+
RemoteContextClientImpl,
|
|
17
|
+
} from "../generated/proto/services";
|
|
18
|
+
import { RestateConnectionOptions } from "./api";
|
|
19
|
+
import { OutgoingHttpHeaders } from "http";
|
|
20
|
+
|
|
21
|
+
export class RequestError extends Error {
|
|
22
|
+
constructor(
|
|
23
|
+
public readonly url: string,
|
|
24
|
+
public readonly status: number,
|
|
25
|
+
public readonly statusText?: string
|
|
26
|
+
) {
|
|
27
|
+
super(`${status} ${statusText ?? ""}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
precondtionFailed(): boolean {
|
|
31
|
+
return this.status === http2.constants.HTTP_STATUS_PRECONDITION_FAILED;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const bufConnectRemoteContext = (
|
|
36
|
+
url: string,
|
|
37
|
+
opt?: RestateConnectionOptions
|
|
38
|
+
): RemoteContext => {
|
|
39
|
+
const httpClient = new ProtobufHttp2Client(url, opt);
|
|
40
|
+
|
|
41
|
+
return new RemoteContextClientImpl({
|
|
42
|
+
request: (service: string, method: string, data: Uint8Array) =>
|
|
43
|
+
httpClient.post(`/${service}/${method}`, data),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
class ProtobufHttp2Client {
|
|
48
|
+
private session?: http2.ClientHttp2Session;
|
|
49
|
+
private additionalHeaders: OutgoingHttpHeaders;
|
|
50
|
+
|
|
51
|
+
public constructor(
|
|
52
|
+
private readonly ingress: string,
|
|
53
|
+
opt?: RestateConnectionOptions
|
|
54
|
+
) {
|
|
55
|
+
this.additionalHeaders = opt?.headers == undefined ? {} : opt?.headers;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private async client(): Promise<http2.ClientHttp2Session> {
|
|
59
|
+
if (this.session !== undefined) {
|
|
60
|
+
return this.session;
|
|
61
|
+
}
|
|
62
|
+
const client = http2.connect(this.ingress);
|
|
63
|
+
client.unref();
|
|
64
|
+
|
|
65
|
+
client.once("goaway", () => {
|
|
66
|
+
this.session = undefined;
|
|
67
|
+
});
|
|
68
|
+
client.once("close", () => {
|
|
69
|
+
this.session = undefined;
|
|
70
|
+
});
|
|
71
|
+
this.session = client;
|
|
72
|
+
return client;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public async post(path: string, body: Uint8Array): Promise<Uint8Array> {
|
|
76
|
+
const client = await this.client();
|
|
77
|
+
|
|
78
|
+
const req = client.request({
|
|
79
|
+
...{
|
|
80
|
+
[http2.constants.HTTP2_HEADER_SCHEME]: "http",
|
|
81
|
+
[http2.constants.HTTP2_HEADER_METHOD]:
|
|
82
|
+
http2.constants.HTTP2_METHOD_POST,
|
|
83
|
+
[http2.constants.HTTP2_HEADER_PATH]: path,
|
|
84
|
+
[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: "application/proto",
|
|
85
|
+
[http2.constants.HTTP2_HEADER_ACCEPT]: "application/proto",
|
|
86
|
+
[http2.constants.HTTP2_HEADER_CONTENT_LENGTH]: body.length,
|
|
87
|
+
},
|
|
88
|
+
...this.additionalHeaders,
|
|
89
|
+
});
|
|
90
|
+
req.end(body);
|
|
91
|
+
|
|
92
|
+
const [headers] = await once(req, "response");
|
|
93
|
+
const status = headers[http2.constants.HTTP2_HEADER_STATUS] ?? 0;
|
|
94
|
+
if (status !== 200) {
|
|
95
|
+
throw new RequestError(path, status);
|
|
96
|
+
}
|
|
97
|
+
const chunks = [];
|
|
98
|
+
for await (const chunk of req) {
|
|
99
|
+
chunks.push(chunk);
|
|
100
|
+
}
|
|
101
|
+
return Buffer.concat(chunks);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
|
|
3
|
+
*
|
|
4
|
+
* This file is part of the Restate SDK for Node.js/TypeScript,
|
|
5
|
+
* which is released under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* You can find a copy of the license in file LICENSE in the root
|
|
8
|
+
* directory of this repository or package, or at
|
|
9
|
+
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { decodeMessagesBuffer } from "../io/decoder";
|
|
13
|
+
import { Message } from "../types/types";
|
|
14
|
+
import {
|
|
15
|
+
GetResultResponse,
|
|
16
|
+
RemoteContext,
|
|
17
|
+
StartRequest,
|
|
18
|
+
} from "../generated/proto/services";
|
|
19
|
+
import { InvocationBuilder } from "../invocation";
|
|
20
|
+
import { HostedGrpcServiceMethod } from "../types/grpc";
|
|
21
|
+
import { StateMachine } from "../state_machine";
|
|
22
|
+
import { ProtocolMode } from "../generated/proto/discovery";
|
|
23
|
+
import {
|
|
24
|
+
EmbeddedConnection,
|
|
25
|
+
FencedOffError,
|
|
26
|
+
} from "../connection/embedded_connection";
|
|
27
|
+
import { RestateInvocationOptions } from "./api";
|
|
28
|
+
|
|
29
|
+
export const doInvoke = async <I, O>(
|
|
30
|
+
remote: RemoteContext,
|
|
31
|
+
operationId: string,
|
|
32
|
+
streamId: string,
|
|
33
|
+
input: I,
|
|
34
|
+
method: HostedGrpcServiceMethod<I, O>,
|
|
35
|
+
opt?: RestateInvocationOptions
|
|
36
|
+
): Promise<O> => {
|
|
37
|
+
//
|
|
38
|
+
// 1. ask to Start this execution.
|
|
39
|
+
//
|
|
40
|
+
|
|
41
|
+
const startRequest = StartRequest.fromPartial({
|
|
42
|
+
operationId,
|
|
43
|
+
streamId,
|
|
44
|
+
argument: Buffer.from(JSON.stringify(input)),
|
|
45
|
+
});
|
|
46
|
+
if (opt != undefined && opt.retain != undefined) {
|
|
47
|
+
startRequest.retentionPeriodSec = opt.retain;
|
|
48
|
+
}
|
|
49
|
+
const res = await remote.start(startRequest);
|
|
50
|
+
|
|
51
|
+
if (res.completed !== undefined) {
|
|
52
|
+
return unwrap(res.completed);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//
|
|
56
|
+
// 2. rebuild the previous execution state
|
|
57
|
+
//
|
|
58
|
+
|
|
59
|
+
const messages = decodeMessagesBuffer(res.executing ?? Buffer.alloc(0));
|
|
60
|
+
const journalBuilder = new InvocationBuilder(method);
|
|
61
|
+
messages.forEach((e: Message) => journalBuilder.handleMessage(e));
|
|
62
|
+
const journal = journalBuilder.build();
|
|
63
|
+
|
|
64
|
+
//
|
|
65
|
+
// 3. resume the execution state machine
|
|
66
|
+
//
|
|
67
|
+
const connection = new EmbeddedConnection(operationId, streamId, remote);
|
|
68
|
+
|
|
69
|
+
const stateMachine = new StateMachine(
|
|
70
|
+
connection,
|
|
71
|
+
journal,
|
|
72
|
+
ProtocolMode.BIDI_STREAM,
|
|
73
|
+
false,
|
|
74
|
+
journal.inferLoggerContext(),
|
|
75
|
+
-1
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
//
|
|
79
|
+
// 4. track the state machine execution result
|
|
80
|
+
//
|
|
81
|
+
let done = false;
|
|
82
|
+
|
|
83
|
+
const invocation = stateMachine.invoke().finally(() => (done = true));
|
|
84
|
+
|
|
85
|
+
//
|
|
86
|
+
// 5. keep pulling for input and feeding this to the fsm.
|
|
87
|
+
//
|
|
88
|
+
try {
|
|
89
|
+
while (!done) {
|
|
90
|
+
const recv = await remote.recv({
|
|
91
|
+
operationId,
|
|
92
|
+
streamId,
|
|
93
|
+
});
|
|
94
|
+
if (recv.invalidStream !== undefined) {
|
|
95
|
+
throw new FencedOffError();
|
|
96
|
+
}
|
|
97
|
+
if (recv.invocationCompleted !== undefined) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
const buffer = recv.messages ?? Buffer.alloc(0);
|
|
101
|
+
const messages = decodeMessagesBuffer(buffer);
|
|
102
|
+
messages.forEach((m: Message) => stateMachine.handleMessage(m));
|
|
103
|
+
}
|
|
104
|
+
} catch (e) {
|
|
105
|
+
stateMachine.handleStreamError(e as Error);
|
|
106
|
+
throw e;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//
|
|
110
|
+
// 6. wait for the state machine to complete the invocation
|
|
111
|
+
//
|
|
112
|
+
const maybeResult = await invocation;
|
|
113
|
+
if (maybeResult instanceof Buffer) {
|
|
114
|
+
return JSON.parse(maybeResult.toString());
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// TODO: no sure what to do here. The state machine has decided to be suspended?
|
|
118
|
+
throw new Error("suspended");
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const unwrap = <O>(response: GetResultResponse): O => {
|
|
122
|
+
if (response.success === undefined) {
|
|
123
|
+
throw new Error(response.failure?.message ?? "");
|
|
124
|
+
}
|
|
125
|
+
return JSON.parse(response.success.toString()) as O;
|
|
126
|
+
};
|