Files
komodo/bin/core/src/helpers/action_state.rs
Maxwell Becker 5fc0a87dea 1.14 - Rename to Komodo - Docker Management (#56)
* setup network page

* add Network, Image, Container

* Docker ListItems and Inspects

* frontend build

* dev0

* network info working

* fix cargo lock

* dev1

* pages for the things

* implement Active in dashboard

* RunBuild update trigger list refresh

* rename deployment executions to StartDeployment etc

* add server level container control

* dev2

* add Config field to Image

* can get image labels from Config.Labels

* mount container page

* server show resource count

* add GetContainerLog api

* add _AllContainers api

* dev3

* move ResourceTarget to entities mod

* GetResourceMatchingContainer api

* connect container to resource

* dev4 add volume names to container list items

* ts types

* volume / image / network unused management

* add image history to image page

* fix PruneContainers incorret Operation

* update cache for server for server after server actions

* dev5

* add singapore to Hetzner

* implement delete single network / image / volume api

* dev6

* include "in use" on Docker Lists

* add docker resource delete buttons

* is nice

* fix volume all in use

* remove google font dependency

* use host networking in test compose

* implement Secret Variables (hidden in logs)

* remove unneeded borrow

* interpolate variables / secrets into extra args / onclone / onpull / command etc

* validate empty strings before SelectItem

* rename everything to Komodo

* rename workspace to komodo

* rc1
2024-09-01 15:38:40 -07:00

99 lines
2.6 KiB
Rust

use std::sync::{Arc, Mutex};
use anyhow::anyhow;
use komodo_client::{
busy::Busy,
entities::{
build::BuildActionState, deployment::DeploymentActionState,
procedure::ProcedureActionState, repo::RepoActionState,
server::ServerActionState, stack::StackActionState,
sync::ResourceSyncActionState,
},
};
use super::cache::Cache;
#[derive(Default)]
pub struct ActionStates {
pub build: Cache<String, Arc<ActionState<BuildActionState>>>,
pub deployment:
Cache<String, Arc<ActionState<DeploymentActionState>>>,
pub server: Cache<String, Arc<ActionState<ServerActionState>>>,
pub repo: Cache<String, Arc<ActionState<RepoActionState>>>,
pub procedure:
Cache<String, Arc<ActionState<ProcedureActionState>>>,
pub resource_sync:
Cache<String, Arc<ActionState<ResourceSyncActionState>>>,
pub stack: Cache<String, Arc<ActionState<StackActionState>>>,
}
/// Need to be able to check "busy" with write lock acquired.
#[derive(Default)]
pub struct ActionState<States: Default + Send + 'static>(
Mutex<States>,
);
impl<States: Default + Busy + Copy + Send + 'static>
ActionState<States>
{
pub fn get(&self) -> anyhow::Result<States> {
Ok(
*self
.0
.lock()
.map_err(|e| anyhow!("action state lock poisoned | {e:?}"))?,
)
}
pub fn busy(&self) -> anyhow::Result<bool> {
Ok(
self
.0
.lock()
.map_err(|e| anyhow!("action state lock poisoned | {e:?}"))?
.busy(),
)
}
/// Will acquire lock, check busy, and if not will
/// run the provided update function on the states.
/// Returns a guard that returns the states to default (not busy) when dropped.
pub fn update(
&self,
handler: impl Fn(&mut States),
) -> anyhow::Result<UpdateGuard<States>> {
let mut lock = self
.0
.lock()
.map_err(|e| anyhow!("action state lock poisoned | {e:?}"))?;
if lock.busy() {
return Err(anyhow!("resource is busy"));
}
handler(&mut *lock);
Ok(UpdateGuard(&self.0))
}
}
/// When dropped will return the inner state to default.
/// The inner mutex guard must already be dropped BEFORE this is dropped,
/// which is guaranteed as the inner guard is dropped by all public methods before
/// user could drop UpdateGuard.
pub struct UpdateGuard<'a, States: Default + Send + 'static>(
&'a Mutex<States>,
);
impl<'a, States: Default + Send + 'static> Drop
for UpdateGuard<'a, States>
{
fn drop(&mut self) {
let mut lock = match self.0.lock() {
Ok(lock) => lock,
Err(e) => {
error!("CRITICAL: an action state lock is poisoned | {e:?}");
return;
}
};
*lock = States::default();
}
}