reactive_graph_plugin_graphql_schema/mutation/
mod.rs

1use std::sync::Arc;
2
3use async_graphql::*;
4
5use reactive_graph_plugin_service_api::PluginContainerManager;
6use reactive_graph_plugin_service_api::PluginResolver;
7
8use crate::query::GraphQLPlugin;
9
10pub struct PluginMutation;
11
12/// Mutations for the plugin system.
13#[Object(name = "Mutation")]
14impl PluginMutation {
15    /// Stops the plugin with the given name.
16    async fn stop(&self, context: &Context<'_>, name: String) -> Result<GraphQLPlugin> {
17        let plugin_container_manager = context.data::<Arc<dyn PluginContainerManager + Send + Sync>>()?;
18        let plugin_resolver = context.data::<Arc<dyn PluginResolver + Send + Sync>>()?;
19        let id = plugin_container_manager.get_id(&name).ok_or_else(|| Error::new("Plugin with name not found"))?;
20        // Stop plugin
21        plugin_container_manager
22            .stop(&id)
23            .map_err(|e| Error::new(format!("Failed to start {}: {:?}", &id, e)))?;
24        // Make all transitions until the plugin and all dependent plugins have stopped
25        plugin_resolver.resolve_until_idle().await;
26        plugin_resolver.transition_to_fallback_states().await;
27        Ok(GraphQLPlugin { id })
28    }
29
30    /// Starts the plugin with the given name.
31    async fn start(&self, context: &Context<'_>, name: String) -> Result<GraphQLPlugin> {
32        let plugin_container_manager = context.data::<Arc<dyn PluginContainerManager + Send + Sync>>()?;
33        let plugin_resolver = context.data::<Arc<dyn PluginResolver + Send + Sync>>()?;
34        let id = plugin_container_manager.get_id(&name).ok_or_else(|| Error::new("Plugin with name not found"))?;
35        // Start plugin
36        plugin_container_manager
37            .start(&id)
38            .map_err(|e| Error::new(format!("Failed to start {}: {:?}", &id, e)))?;
39        // Make all transitions until the plugin has started
40        plugin_resolver.resolve_until_idle().await;
41        // Start dependent plugins
42        while plugin_container_manager.start_dependent_with_satisfied_dependencies(&id) {
43            // Resolve until all dependent plugins are started
44            plugin_resolver.resolve_until_idle().await;
45        }
46        plugin_resolver.transition_to_fallback_states().await;
47        Ok(GraphQLPlugin { id })
48    }
49
50    /// Restarts the plugin with the given name.
51    async fn restart(&self, context: &Context<'_>, name: String) -> Result<GraphQLPlugin> {
52        let plugin_container_manager = context.data::<Arc<dyn PluginContainerManager + Send + Sync>>()?;
53        let plugin_resolver = context.data::<Arc<dyn PluginResolver + Send + Sync>>()?;
54        let id = plugin_container_manager.get_id(&name).ok_or_else(|| Error::new("Plugin with name not found"))?;
55        // Stop plugin
56        plugin_container_manager
57            .stop(&id)
58            .map_err(|e| Error::new(format!("Failed to start {}: {:?}", &id, e)))?;
59        // Make all transitions until the plugin and all dependent plugins have stopped
60        plugin_resolver.resolve_until_idle().await;
61        // Start plugin
62        plugin_container_manager
63            .start(&id)
64            .map_err(|e| Error::new(format!("Failed to start {}: {:?}", &id, e)))?;
65        // Make all transitions until the plugin has started
66        plugin_resolver.resolve_until_idle().await;
67        // Start dependent plugins
68        while plugin_container_manager.start_dependent_with_satisfied_dependencies(&id) {
69            // Resolve until all dependent plugins are started
70            plugin_resolver.resolve_until_idle().await;
71        }
72        plugin_resolver.transition_to_fallback_states().await;
73        Ok(GraphQLPlugin { id })
74    }
75
76    /// Uninstalls the plugin with the given name.
77    async fn uninstall(&self, context: &Context<'_>, name: String) -> Result<bool> {
78        let plugin_container_manager = context.data::<Arc<dyn PluginContainerManager + Send + Sync>>()?;
79        let plugin_resolver = context.data::<Arc<dyn PluginResolver + Send + Sync>>()?;
80        let id = plugin_container_manager.get_id(&name).ok_or_else(|| Error::new("Plugin with name not found"))?;
81        // plugin_container_manager.set_state(&id)
82        plugin_container_manager
83            .uninstall(&id)
84            .map_err(|e| Error::new(format!("Failed to uninstall {}: {:?}", &id, e)))?;
85        plugin_resolver.resolve_until_idle().await;
86        plugin_resolver.transition_to_fallback_states().await;
87        Ok(true)
88    }
89
90    /// Redeploys a plugin which is already installed, resolved or active.
91    async fn redeploy(&self, context: &Context<'_>, name: String) -> Result<GraphQLPlugin> {
92        let plugin_container_manager = context.data::<Arc<dyn PluginContainerManager + Send + Sync>>()?;
93        let plugin_resolver = context.data::<Arc<dyn PluginResolver + Send + Sync>>()?;
94        let id = plugin_container_manager.get_id(&name).ok_or_else(|| Error::new("Plugin with name not found"))?;
95        plugin_container_manager
96            .redeploy(&id)
97            .map_err(|e| Error::new(format!("Failed to start {}: {:?}", &id, e)))?;
98        plugin_resolver.resolve_until_idle().await;
99        plugin_resolver.transition_to_fallback_states().await;
100        Ok(GraphQLPlugin { id })
101    }
102}