canic_core/ops/storage/
pool.rs1use crate::{
2 Error,
3 cdk::utils::time::now_secs,
4 dto::pool::{CanisterPoolEntryView, CanisterPoolView},
5 model::memory::pool::{
6 CanisterPool, CanisterPoolData, CanisterPoolEntry, CanisterPoolState, CanisterPoolStatus,
7 },
8 ops::{
9 adapter::pool::{canister_pool_entry_to_view, canister_pool_to_view},
10 config::ConfigOps,
11 prelude::*,
12 },
13};
14
15pub struct PoolOps;
26
27impl PoolOps {
28 pub fn register_ready(
33 pid: Principal,
34 cycles: Cycles,
35 role: Option<CanisterRole>,
36 parent: Option<Principal>,
37 module_hash: Option<Vec<u8>>,
38 ) {
39 let created_at = now_secs();
40 CanisterPool::register(
41 pid,
42 cycles,
43 CanisterPoolStatus::Ready,
44 role,
45 parent,
46 module_hash,
47 created_at,
48 );
49 }
50
51 pub fn mark_pending_reset(pid: Principal) {
56 Self::register_or_update_state(
57 pid,
58 Cycles::default(),
59 CanisterPoolStatus::PendingReset,
60 None,
61 );
62 }
63
64 pub fn mark_ready(pid: Principal, cycles: Cycles) {
65 Self::register_or_update_state(pid, cycles, CanisterPoolStatus::Ready, None);
66 }
67
68 pub fn mark_failed(pid: Principal, err: &Error) {
69 let status = CanisterPoolStatus::Failed {
70 reason: err.to_string(),
71 };
72 Self::register_or_update_state(pid, Cycles::default(), status, None);
73 }
74
75 #[must_use]
80 pub fn get_view(pid: Principal) -> Option<CanisterPoolEntryView> {
81 CanisterPool::get(pid).map(|entry| canister_pool_entry_to_view(&entry.header, &entry.state))
82 }
83
84 #[must_use]
87 pub fn export() -> CanisterPoolData {
88 CanisterPool::export()
89 }
90
91 #[must_use]
92 pub fn export_view() -> CanisterPoolView {
93 let data = CanisterPool::export();
94 canister_pool_to_view(data)
95 }
96
97 #[must_use]
102 pub(crate) fn pop_ready() -> Option<(Principal, CanisterPoolEntry)> {
103 CanisterPool::pop_ready()
104 }
105
106 #[must_use]
107 pub fn contains(pid: &Principal) -> bool {
108 CanisterPool::contains(pid)
109 }
110
111 #[must_use]
112 pub(crate) fn take(pid: &Principal) -> Option<CanisterPoolEntry> {
113 CanisterPool::take(pid)
114 }
115
116 #[must_use]
117 pub fn len() -> u64 {
118 CanisterPool::len()
119 }
120
121 fn register_or_update_state(
126 pid: Principal,
127 cycles: Cycles,
128 status: CanisterPoolStatus,
129 role: Option<CanisterRole>,
130 ) {
131 let updated = CanisterPool::update_state_with(pid, |mut state: CanisterPoolState| {
133 state.cycles = cycles.clone();
134 state.status = status.clone();
135
136 if role.is_some() {
138 state.role.clone_from(&role);
139 }
140
141 state
142 });
143
144 if !updated {
145 let created_at = now_secs();
147 CanisterPool::register(pid, cycles, status, role, None, None, created_at);
148 }
149 }
150}
151
152pub fn pool_controllers() -> Result<Vec<Principal>, Error> {
170 let mut controllers = ConfigOps::controllers()?;
171
172 let root = canister_self();
173 if !controllers.contains(&root) {
174 controllers.push(root);
175 }
176
177 Ok(controllers)
178}