awaken_runtime/extensions/background/
state.rs1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::state::StateKey;
6
7use super::types::{TaskId, TaskParentContext, TaskStatus, TaskSummary};
8
9#[derive(Debug, Clone, Default, Serialize, Deserialize)]
11pub struct BackgroundTaskView {
12 pub tasks: HashMap<String, TaskViewEntry>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct TaskViewEntry {
18 pub task_type: String,
19 pub description: String,
20 pub status: TaskStatus,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub enum BackgroundTaskViewAction {
26 Replace {
27 tasks: HashMap<String, TaskViewEntry>,
28 },
29 Clear,
30}
31
32impl BackgroundTaskView {
33 pub(crate) fn reduce(&mut self, action: BackgroundTaskViewAction) {
34 match action {
35 BackgroundTaskViewAction::Replace { tasks } => {
36 self.tasks = tasks;
37 }
38 BackgroundTaskViewAction::Clear => {
39 self.tasks.clear();
40 }
41 }
42 }
43}
44
45pub struct BackgroundTaskViewKey;
47
48impl StateKey for BackgroundTaskViewKey {
49 const KEY: &'static str = "background_tasks";
50 type Value = BackgroundTaskView;
51 type Update = BackgroundTaskViewAction;
52
53 fn apply(value: &mut Self::Value, update: Self::Update) {
54 value.reduce(update);
55 }
56}
57
58#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct PersistedTaskMeta {
64 pub task_id: TaskId,
65 #[serde(default)]
66 pub owner_thread_id: String,
67 pub task_type: String,
68 #[serde(default, skip_serializing_if = "Option::is_none")]
70 pub name: Option<String>,
71 pub description: String,
73 pub status: TaskStatus,
74 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub error: Option<String>,
76 #[serde(default, skip_serializing_if = "Option::is_none")]
77 pub result: Option<serde_json::Value>,
78 pub created_at_ms: u64,
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub completed_at_ms: Option<u64>,
81 #[serde(default)]
82 pub parent_context: TaskParentContext,
83}
84
85impl PersistedTaskMeta {
86 pub fn from_summary(summary: &TaskSummary, owner_thread_id: &str) -> Self {
88 Self {
89 task_id: summary.task_id.clone(),
90 owner_thread_id: owner_thread_id.to_string(),
91 task_type: summary.task_type.clone(),
92 name: None,
93 description: summary.description.clone(),
94 status: summary.status,
95 error: summary.error.clone(),
96 result: summary.result.clone(),
97 created_at_ms: summary.created_at_ms,
98 completed_at_ms: summary.completed_at_ms,
99 parent_context: summary.parent_context.clone(),
100 }
101 }
102}
103
104#[derive(Debug, Clone, Default, Serialize, Deserialize)]
106pub struct BackgroundTaskStateSnapshot {
107 pub tasks: HashMap<TaskId, PersistedTaskMeta>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112pub enum BackgroundTaskStateAction {
113 Upsert(Box<PersistedTaskMeta>),
115 ReplaceAll {
117 tasks: HashMap<TaskId, PersistedTaskMeta>,
118 },
119}
120
121impl BackgroundTaskStateSnapshot {
122 pub(crate) fn reduce(&mut self, action: BackgroundTaskStateAction) {
123 match action {
124 BackgroundTaskStateAction::Upsert(meta) => {
125 self.tasks.insert(meta.task_id.clone(), *meta);
126 }
127 BackgroundTaskStateAction::ReplaceAll { tasks } => {
128 self.tasks = tasks;
129 }
130 }
131 }
132}
133
134pub struct BackgroundTaskStateKey;
140
141impl StateKey for BackgroundTaskStateKey {
142 const KEY: &'static str = "background_task_state";
143 type Value = BackgroundTaskStateSnapshot;
144 type Update = BackgroundTaskStateAction;
145
146 fn apply(value: &mut Self::Value, update: Self::Update) {
147 value.reduce(update);
148 }
149}