1use crate::{
17 cdk::types::Cycles,
18 dto::{prelude::*, rpc::RootRequestMetadata},
19};
20
21pub use crate::domain::pool::CanisterPoolStatus;
22
23#[derive(CandidType, Clone, Debug, Deserialize)]
29pub struct CanisterPoolResponse {
30 pub entries: Vec<CanisterPoolEntry>,
31}
32
33#[derive(CandidType, Clone, Debug, Deserialize)]
38pub struct CanisterPoolEntry {
39 pub pid: Principal,
40 pub created_at: u64,
41 pub cycles: Cycles,
42 pub status: CanisterPoolStatus,
43 pub role: Option<CanisterRole>,
44 pub parent: Option<Principal>,
45 pub module_hash: Option<Vec<u8>>,
46}
47
48#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
56pub enum PoolAdminCommand {
57 CreateEmpty(CreateEmptyPoolRequest),
59
60 Recycle { pid: Principal },
62
63 ImportImmediate { pid: Principal },
65
66 ImportQueued { pids: Vec<Principal> },
68}
69
70#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
75pub struct CreateEmptyPoolRequest {
76 #[serde(default)]
77 pub metadata: Option<RootRequestMetadata>,
78}
79
80#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
86pub enum PoolAdminResponse {
87 Created { pid: Principal },
89
90 Recycled,
92
93 Imported,
95
96 QueuedImported { result: PoolBatchResult },
98
99 FailedRequeued { result: PoolBatchResult },
101}
102
103#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
108pub struct PoolBatchResult {
109 pub total: u64,
110 pub added: u64,
111 pub requeued: u64,
112 pub skipped: u64,
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn reexported_pool_status_roundtrips_through_candid() {
121 let entry = CanisterPoolEntry {
122 pid: Principal::from_slice(&[3; 29]),
123 created_at: 42,
124 cycles: Cycles::new(10_000),
125 status: crate::domain::pool::CanisterPoolStatus::Failed {
126 reason: "bounded reset failure".to_string(),
127 },
128 role: Some(CanisterRole::new("worker")),
129 parent: None,
130 module_hash: Some(vec![1, 2, 3]),
131 };
132
133 let bytes = candid::encode_one(&entry).expect("encode pool entry");
134 let decoded: CanisterPoolEntry = candid::decode_one(&bytes).expect("decode pool entry");
135
136 let dto_status: CanisterPoolStatus = crate::domain::pool::CanisterPoolStatus::Failed {
137 reason: "bounded reset failure".to_string(),
138 };
139
140 assert_eq!(decoded.pid, Principal::from_slice(&[3; 29]));
141 assert_eq!(decoded.created_at, 42);
142 assert_eq!(decoded.cycles, Cycles::new(10_000));
143 assert_eq!(decoded.status, dto_status);
144 assert_eq!(decoded.role, Some(CanisterRole::new("worker")));
145 assert_eq!(decoded.parent, None);
146 assert_eq!(decoded.module_hash, Some(vec![1, 2, 3]));
147 }
148}