linera_base/task_processor.rs
1// Copyright (c) Facebook, Inc. and its affiliates.
2// Copyright (c) Zefchain Labs, Inc.
3// SPDX-License-Identifier: Apache-2.0
4
5//! Types related to the task processor features in the node service.
6
7use async_graphql::scalar;
8use serde::{Deserialize, Serialize};
9
10use crate::data_types::Timestamp;
11
12/// The off-chain actions requested by the service of an on-chain application.
13///
14/// On-chain applications should be ready to respond to GraphQL queries of the form:
15/// ```ignore
16/// query {
17/// nextActions(lastRequestedCallback: Timestamp, now: Timestamp!): ProcessorActions!
18/// }
19///
20/// query {
21/// processTaskOutcome(outcome: TaskOutcome!)
22/// }
23/// ```
24#[derive(Default, Debug, Serialize, Deserialize)]
25pub struct ProcessorActions {
26 /// The application is requesting to be called back no later than the given timestamp.
27 pub request_callback: Option<Timestamp>,
28 /// An optional cursor for the task processor to store and pass to the application
29 /// upon the next query for actions.
30 pub set_cursor: Option<String>,
31 /// The application is requesting the execution of the given tasks.
32 ///
33 /// Tasks are grouped by [`id`](Task::id), the ones without an id forming a single group.
34 /// The outcomes of distinct groups commute: each is submitted as soon as its task
35 /// succeeds, in no guaranteed order relative to the other groups, and a task that fails is
36 /// retried without holding the other groups back. Within a group the outcomes are
37 /// submitted in the order of this vector and submission stops at the first failure, so
38 /// that an application matching them by position never sees a gap.
39 pub execute_tasks: Vec<Task>,
40}
41
42scalar!(ProcessorActions);
43
44/// An off-chain task requested by an on-chain application.
45#[derive(Debug, Serialize, Deserialize)]
46pub struct Task {
47 /// An opaque, application-defined identifier, echoed back in the [`TaskOutcome`].
48 ///
49 /// Applications that set it match outcomes by identity rather than by position. An id
50 /// distinct from the id of every other task of the batch makes the outcome independent of
51 /// all of them; see [`ProcessorActions::execute_tasks`].
52 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub id: Option<String>,
54 /// The operator handling the task.
55 pub operator: String,
56 /// The input argument in JSON.
57 pub input: String,
58}
59
60/// The result of executing an off-chain operator.
61#[derive(Debug, Serialize, Deserialize)]
62pub struct TaskOutcome {
63 /// The identifier of the [`Task`] this outcome belongs to, if it had one.
64 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub id: Option<String>,
66 /// The operator handling the task.
67 pub operator: String,
68 /// The JSON output.
69 pub output: String,
70}
71
72scalar!(TaskOutcome);