feat: submitStreaming + detached-invocation client (T2/T3)
Some checks failed
Security / Security check (push) Failing after 2s
Some checks failed
Security / Security check (push) Failing after 2s
Regenerates the gRPC stubs from the updated proto and adds: - HubClient.submitStreaming(...) -> Stream<SubmitStreamEvent>: follow a flow execution live (step markers, module emit-events, terminal result/error). Works over native gRPC and, on web, gRPC-Web (the same conditional channel factory the rest of the SDK uses). - submit(..., detach: true) and getInvocationStatus / getInvocationResult / cancelInvocation wrappers (T3). - SubmitStreamEvent + InvocationStatus re-exported as typedefs. Shared _buildSubmitRequest between submit + submitStreaming. analyze clean, tests pass. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
0d2e939867
commit
c46dc58ac3
5 changed files with 1038 additions and 5 deletions
|
|
@ -86,6 +86,11 @@ typedef StoreSearchResponse = pb.StoreSearchResponse;
|
|||
typedef InstallModuleResponse = pb.InstallModuleResponse;
|
||||
typedef Payload = pb_common.Payload;
|
||||
typedef SubmitResponse = pb.SubmitResponse;
|
||||
// Live-stream (T2) + detached-invocation (T3) wire types, re-exported
|
||||
// so consumers of [HubClient.submitStreaming] don't import the
|
||||
// generated package directly.
|
||||
typedef SubmitStreamEvent = pb.SubmitStreamEvent;
|
||||
typedef InvocationStatus = pb.InvocationStatus;
|
||||
|
||||
/// Typed client for the F∆I Hub gRPC surface. Construct once,
|
||||
/// reuse for the process lifetime, call [close] on shutdown.
|
||||
|
|
@ -779,8 +784,80 @@ class HubClient {
|
|||
Map<String, Uint8List> fileInputs = const {},
|
||||
Map<String, Object?> jsonInputs = const {},
|
||||
Map<String, String> fileMimeTypes = const {},
|
||||
bool detach = false,
|
||||
}) async {
|
||||
final req = pb.SubmitRequest()..flowYaml = utf8.encode(flowYaml);
|
||||
return _hub.submit(_buildSubmitRequest(
|
||||
flowYaml: flowYaml,
|
||||
textInputs: textInputs,
|
||||
fileInputs: fileInputs,
|
||||
jsonInputs: jsonInputs,
|
||||
fileMimeTypes: fileMimeTypes,
|
||||
detach: detach,
|
||||
));
|
||||
}
|
||||
|
||||
/// Submit a flow and follow its execution live (server streaming).
|
||||
///
|
||||
/// Yields [pb.SubmitStreamEvent]s in order: `stepStarted` /
|
||||
/// `stepFinished` markers, `moduleEvent`s (a module's ephemeral
|
||||
/// `host.emit-event`s), and finally either `finalResult` (== the
|
||||
/// unary [submit] response) or `error`. Works over native gRPC and,
|
||||
/// on web targets, gRPC-Web. Same inputs as [submit].
|
||||
///
|
||||
/// ```dart
|
||||
/// await for (final ev in hub.submitStreaming(flowYaml: yaml)) {
|
||||
/// if (ev.hasModuleEvent()) print('${ev.moduleEvent.name}');
|
||||
/// if (ev.hasFinalResult()) print(ev.finalResult.outputs);
|
||||
/// }
|
||||
/// ```
|
||||
Stream<SubmitStreamEvent> submitStreaming({
|
||||
required String flowYaml,
|
||||
Map<String, String> textInputs = const {},
|
||||
Map<String, Uint8List> fileInputs = const {},
|
||||
Map<String, Object?> jsonInputs = const {},
|
||||
Map<String, String> fileMimeTypes = const {},
|
||||
}) {
|
||||
return _hub.submitStream(_buildSubmitRequest(
|
||||
flowYaml: flowYaml,
|
||||
textInputs: textInputs,
|
||||
fileInputs: fileInputs,
|
||||
jsonInputs: jsonInputs,
|
||||
fileMimeTypes: fileMimeTypes,
|
||||
));
|
||||
}
|
||||
|
||||
/// Status of a detached invocation (T3). Throws a [GrpcError] with
|
||||
/// code `notFound` for an unknown id.
|
||||
Future<InvocationStatus> getInvocationStatus(String invocationId) {
|
||||
return _hub.getInvocationStatus(pb_common.InvocationId()..value = invocationId);
|
||||
}
|
||||
|
||||
/// Retained result of a succeeded detached invocation (T3). Throws
|
||||
/// `failedPrecondition` if it is still running / failed, `notFound`
|
||||
/// if unknown or already evicted.
|
||||
Future<SubmitResponse> getInvocationResult(String invocationId) {
|
||||
return _hub.getInvocationResult(pb_common.InvocationId()..value = invocationId);
|
||||
}
|
||||
|
||||
/// Cancel a running detached invocation (T3). Returns true if it was
|
||||
/// running and got signalled, false if already finished or unknown.
|
||||
Future<bool> cancelInvocation(String invocationId) async {
|
||||
final r =
|
||||
await _hub.cancelInvocation(pb_common.InvocationId()..value = invocationId);
|
||||
return r.cancelled;
|
||||
}
|
||||
|
||||
pb.SubmitRequest _buildSubmitRequest({
|
||||
required String flowYaml,
|
||||
required Map<String, String> textInputs,
|
||||
required Map<String, Uint8List> fileInputs,
|
||||
required Map<String, Object?> jsonInputs,
|
||||
required Map<String, String> fileMimeTypes,
|
||||
bool detach = false,
|
||||
}) {
|
||||
final req = pb.SubmitRequest()
|
||||
..flowYaml = utf8.encode(flowYaml)
|
||||
..detach = detach;
|
||||
for (final entry in textInputs.entries) {
|
||||
req.inputs[entry.key] = pb_common.Payload()..text = entry.value;
|
||||
}
|
||||
|
|
@ -801,7 +878,7 @@ class HubClient {
|
|||
}
|
||||
req.inputs[entry.key] = pb_common.Payload()..json = _structFromMap(value);
|
||||
}
|
||||
return _hub.submit(req);
|
||||
return req;
|
||||
}
|
||||
|
||||
/// Closes the gRPC channel. Idempotent.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue