feat: update container info ir running OR restarting

refactor: dockerdata thread hashmap insertion
This commit is contained in:
Jack Wills
2022-09-07 03:03:49 +00:00
parent 18713c091e
commit 5f12362db7
+38 -39
View File
@@ -1,6 +1,7 @@
use bollard::{ use bollard::{
container::{ListContainersOptions, LogsOptions, StartContainerOptions, Stats, StatsOptions}, container::{ListContainersOptions, LogsOptions, StartContainerOptions, Stats, StatsOptions},
Docker, service::ContainerSummary, service::ContainerSummary,
Docker,
}; };
use futures_util::StreamExt; use futures_util::StreamExt;
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -80,7 +81,7 @@ impl DockerData {
/// Get a single docker stat in order to update mem and cpu usage /// Get a single docker stat in order to update mem and cpu usage
/// don't take &self, so that can tokio::spawn into it's own thread /// don't take &self, so that can tokio::spawn into it's own thread
/// remove if from spawns hashmap when complete /// remove from spawns hashmap when complete
async fn update_container_stat( async fn update_container_stat(
docker: Arc<Docker>, docker: Arc<Docker>,
id: String, id: String,
@@ -145,25 +146,23 @@ impl DockerData {
let spawns = Arc::clone(&self.spawns); let spawns = Arc::clone(&self.spawns);
let is_running = *is_running; let is_running = *is_running;
let id = id.clone(); let id = id.clone();
let key = SpawnId::Stats(id.clone()); let key = SpawnId::Stats(id.clone());
let spawn_contains_id = spawns.lock().contains_key(&key);
let s = tokio::spawn(Self::update_container_stat( self.spawns.lock().entry(key).or_insert_with(|| {
docker, tokio::spawn(Self::update_container_stat(
id.clone(), docker,
app_data, id.clone(),
is_running, app_data,
spawns, is_running,
)); spawns,
if !spawn_contains_id { ))
self.spawns.lock().insert(key, s); });
}
} }
} }
/// Get all current containers, handle into ContainerItem in the app_data struct rather than here /// Get all current containers, handle into ContainerItem in the app_data struct rather than here
/// Just make sure that items sent are guaranteed to have an id /// Just make sure that items sent are guaranteed to have an id
/// Will ignore any container that uses `oxker` as an entry point /// Will ignore any container that contains `oxker` as an entry point
pub async fn update_all_containers(&mut self) -> Vec<(bool, String)> { pub async fn update_all_containers(&mut self) -> Vec<(bool, String)> {
let containers = self let containers = self
.docker .docker
@@ -174,32 +173,33 @@ impl DockerData {
.await .await
.unwrap_or_default(); .unwrap_or_default();
let output = containers let mut output = containers
.iter() .iter()
.filter_map(|f| match f.id { .filter_map(|f| match f.id {
Some(_) => { Some(_) => {
if f.command.as_ref().map_or(false, |c|c.contains("oxker")) { if f.command.as_ref().map_or(false, |c| c.contains("oxker")) {
None None
} else { } else {
Some(f.clone()) Some(f.clone())
} }
}, }
None => None, None => None,
}) })
.collect::<Vec<ContainerSummary>>(); .collect::<Vec<ContainerSummary>>();
self.app_data.lock().update_containers(&output); self.app_data.lock().update_containers(&mut output);
let current_sort = self.app_data.lock().get_sorted(); let current_sort = self.app_data.lock().get_sorted();
self.app_data.lock().set_sorted(current_sort); self.app_data.lock().set_sorted(current_sort);
// Just get the containers that are currently running, no point updating info on paused or dead containers // Just get the containers that are currently running, or being restarted, no point updating info on paused or dead containers
output output
.iter() .iter()
.filter_map(|i| { .filter_map(|i| {
i.id.as_ref().map(|id| { i.id.as_ref().map(|id| {
( (
i.state == Some("running".to_owned()), i.state == Some("running".to_owned())
|| i.state == Some("restarting".to_owned()),
id.clone(), id.clone(),
) )
}) })
@@ -250,11 +250,12 @@ impl DockerData {
let app_data = Arc::clone(&self.app_data); let app_data = Arc::clone(&self.app_data);
let spawns = Arc::clone(&self.spawns); let spawns = Arc::clone(&self.spawns);
let key = SpawnId::Log(id.clone()); let key = SpawnId::Log(id.clone());
let s = tokio::spawn(Self::update_log( self.spawns.lock().insert(
docker, id, timestamps, 0, app_data, spawns, key,
)); tokio::spawn(Self::update_log(
docker, id, timestamps, 0, app_data, spawns,
self.spawns.lock().insert(key, s); )),
);
} }
} }
@@ -341,14 +342,11 @@ impl DockerData {
} }
DockerMessage::Restart(id) => { DockerMessage::Restart(id) => {
let loading_spin = self.loading_spin().await; let loading_spin = self.loading_spin().await;
if docker if docker.restart_container(&id, None).await.is_err() {
.restart_container(&id, None) app_data
.await .lock()
.is_err() { .set_error(AppError::DockerCommand(DockerControls::Restart));
app_data };
.lock()
.set_error(AppError::DockerCommand(DockerControls::Restart));
};
self.stop_loading_spin(&loading_spin); self.stop_loading_spin(&loading_spin);
} }
DockerMessage::Start(id) => { DockerMessage::Start(id) => {
@@ -356,11 +354,12 @@ impl DockerData {
if docker if docker
.start_container(&id, None::<StartContainerOptions<String>>) .start_container(&id, None::<StartContainerOptions<String>>)
.await .await
.is_err() { .is_err()
app_data {
.lock() app_data
.set_error(AppError::DockerCommand(DockerControls::Start)); .lock()
}; .set_error(AppError::DockerCommand(DockerControls::Start));
};
self.stop_loading_spin(&loading_spin); self.stop_loading_spin(&loading_spin);
} }
DockerMessage::Stop(id) => { DockerMessage::Stop(id) => {