driver_manager_node/
shutdown.rs1use crate::node::Node;
6use async_trait::async_trait;
7use driver_manager_driver_host::DriverHost;
8use driver_manager_shutdown::{
9 NodeInfo, NodeShutdownBridge, NodeShutdownCoordinator, ShutdownIntent, ShutdownNode,
10};
11use driver_manager_types::{Collection, ShutdownState};
12use log::{debug, error, warn};
13use std::rc::{Rc, Weak};
14
15pub struct NodeBridge(Weak<Node>);
16
17impl NodeBridge {
18 pub fn new(node: Weak<Node>) -> Self {
19 Self(node)
20 }
21}
22
23#[async_trait(?Send)]
24impl ShutdownNode for Node {
25 fn get_shutdown_coordinator(&self) -> std::cell::RefMut<'_, NodeShutdownCoordinator> {
26 self.node_shutdown_coordinator.borrow_mut()
27 }
28 fn name(&self) -> &str {
29 &self.name
30 }
31 async fn finish_shutdown(&self) {
32 if let Some(this) = self.weak_self.upgrade() {
33 this.finish_shutdown().await;
34 }
35 }
36 fn schedule_post_shutdown(&self, intent: ShutdownIntent) {
37 if let Some(this) = self.weak_self.upgrade() {
38 this.schedule_post_shutdown(intent);
39 }
40 }
41 fn set_should_destroy_driver_component(&self, val: bool) {
42 self.set_should_destroy_driver_component(val);
43 }
44}
45
46#[async_trait(?Send)]
47impl NodeShutdownBridge for NodeBridge {
48 fn get_removal_tracker_info(&self, shutdown_state: ShutdownState) -> NodeInfo {
49 if let Some(node) = self.0.upgrade() {
50 NodeInfo {
51 name: node.make_component_moniker(),
52 driver_url: node.driver_url(),
53 collection: node.collection(),
54 state: shutdown_state,
55 host: node.driver_host(),
56 }
57 } else {
58 NodeInfo {
60 name: "".to_string(),
61 driver_url: "".to_string(),
62 collection: Collection::None,
63 state: ShutdownState::Stopped,
64 host: None,
65 }
66 }
67 }
68 fn stop_driver(&self) {
69 if let Some(node) = self.0.upgrade() {
70 node.stop_driver();
71 }
72 }
73 fn stop_driver_component(&self) {
74 if let Some(node) = self.0.upgrade() {
75 node.stop_driver_component();
76 }
77 }
78 fn is_pending_bind(&self) -> bool {
79 if let Some(node) = self.0.upgrade() { node.is_pending_bind() } else { false }
80 }
81 fn has_children(&self) -> bool {
82 if let Some(node) = self.0.upgrade() { !node.children().is_empty() } else { false }
83 }
84 fn has_driver(&self) -> bool {
85 if let Some(node) = self.0.upgrade() { node.has_driver() } else { false }
86 }
87 fn has_driver_component(&self) -> bool {
88 if let Some(node) = self.0.upgrade() { node.has_driver_component() } else { false }
89 }
90 fn has_driver_component_controller(&self) -> bool {
91 if let Some(node) = self.0.upgrade() {
92 node.has_component_controller_proxy()
93 } else {
94 false
95 }
96 }
97 fn maybe_destroy_driver_component(&self, intent: ShutdownIntent) -> bool {
98 if let Some(node) = self.0.upgrade() {
99 node.maybe_destroy_driver_component(intent)
100 } else {
101 false
102 }
103 }
104 fn get_driver_host(&self) -> Option<Rc<dyn DriverHost>> {
105 let node = self.0.upgrade()?;
106 node.driver_host()
107 }
108 fn collection(&self) -> Collection {
109 if let Some(node) = self.0.upgrade() { node.collection() } else { Collection::None }
110 }
111 fn children(&self) -> Vec<Rc<dyn ShutdownNode>> {
112 if let Some(node) = self.0.upgrade() {
113 node.children().into_iter().map(|c| c as Rc<dyn ShutdownNode>).collect()
114 } else {
115 vec![]
116 }
117 }
118 fn get_weak_node(&self) -> Weak<dyn ShutdownNode> {
119 self.0.clone() as Weak<dyn ShutdownNode>
120 }
121}
122
123impl Node {
124 fn remove_child(&self, child: &Rc<Node>) {
125 log::debug!("RemoveChild {} from parent {}", child.name(), self.name());
126 if self.remove_child_from_children(child) {
127 self.node_shutdown_coordinator.borrow_mut().check_node_state();
128 }
129 }
130
131 async fn finish_shutdown(self: &Rc<Self>) {
132 log::debug!("Node: {} finishing shutdown", self.make_component_moniker());
133
134 if let Some(koid) = self.token_koid()
135 && let Some(attributor) = self.node_manager.memory_attributor()
136 {
137 attributor.remove_driver(koid.raw_koid());
138 }
139
140 if let Some(b) = self.take_node_controller() {
141 b.close()
142 }
143
144 self.finish_shutdown_state();
145
146 for parent in self.parents() {
147 if let Some(p) = parent.upgrade() {
148 p.remove_child(self);
149 } else if !self.is_root_node() {
150 warn!("Parent freed before child {} could be removed from it", self.name());
151 }
152 }
153
154 self.reset_node_type();
155 }
156
157 fn schedule_post_shutdown(self: &Rc<Self>, intent: ShutdownIntent) {
158 let self_clone = self.clone();
159 self.scope.spawn_local(async move {
160 self_clone.post_shutdown(intent).await;
161 });
162 }
163
164 async fn post_shutdown(self: &Rc<Self>, intent: ShutdownIntent) {
165 if let Some(koid) = self.token_koid()
166 && let Some(attributor) = self.node_manager.memory_attributor()
167 {
168 attributor.remove_driver(koid.raw_koid());
169 }
170
171 if intent == ShutdownIntent::Restart {
172 log::debug!("Node '{}': finishing restart", self.make_component_moniker());
173 self.finish_restart().await;
174 return;
175 } else if intent == ShutdownIntent::Quarantine {
176 log::debug!("Node '{}': finishing quarantine", self.make_component_moniker());
177 self.finish_quarantine();
178 return;
179 }
180
181 if let Some(cb) = self.take_remove_complete_callback() {
182 let _ = cb.send(());
183 }
184
185 if intent == ShutdownIntent::RebindComposite
186 && let Some(completer) = self.take_composite_rebind_completer()
187 {
188 let _ = completer.send(Ok(()));
189 }
190 }
191
192 async fn finish_restart(self: &Rc<Self>) {
193 self.get_shutdown_coordinator().reset_shutdown();
194 let previous_url = self.driver_url();
196
197 self.finish_restart_state();
199
200 if self.host_restart_on_crash() {
201 self.take_host();
202 }
203
204 let suffix = self.take_restart_driver_url_suffix();
205 if let Some(suffix) = suffix {
206 let tracker = self.create_bind_result_tracker(false);
207 self.node_manager.bind_to_url(self, &suffix, tracker);
208 return;
209 }
210
211 let package_type = self.driver_package_type();
212 if let Err(e) = self.node_manager.start_driver(self, &previous_url, package_type) {
213 error!("Failed to start driver '{}': {}", self.name(), e);
214 }
215 }
216
217 fn finish_quarantine(self: &Rc<Self>) {
218 self.get_shutdown_coordinator().reset_shutdown();
219 assert!(self.is_quarantined(), "Node::state_ was not set to Quarantined");
220 }
221
222 fn stop_driver(&self) {
223 if self.is_pending_bind() {
224 warn!(
225 "Stopping driver for node '{}' while bind is in process",
226 self.make_component_moniker()
227 );
228 return;
229 }
230
231 if let Some(driver) = self.driver_client_binding()
232 && let Err(e) = driver.stop()
233 {
234 error!("Node: {} failed to stop driver: {}", self.name(), e);
235 self.clear_driver_host();
236 }
237 }
238
239 fn maybe_destroy_driver_component(self: &Rc<Self>, intent: ShutdownIntent) -> bool {
240 if self.should_destroy_driver_component()
241 || intent != ShutdownIntent::Removal
242 || self.has_remove_complete_callback()
243 || self.is_root_node()
244 {
245 let Some(proxy) = self.component_controller_proxy() else {
246 return false;
247 };
248
249 let name = self.make_component_moniker();
250
251 let self_rc = self.clone();
252 self.scope.spawn_local(async move {
253 let e = proxy.destroy().await;
254 match e {
255 Ok(inner) => match inner {
256 Ok(()) => (),
257 Err(e) => {
258 error!("Node: '{}' destroy failed: {:?}", name, e);
259 }
260 },
261 Err(e) => {
262 error!("Node: '{}' failed to send destroy: {:?}", name, e);
263 }
264 }
265
266 self_rc.set_should_destroy_driver_component(false);
267 });
268
269 return true;
270 }
271
272 debug!("Node: '{}' not destroying", self.make_component_moniker());
273 false
274 }
275}