OneLauncher-Cracked/packages/core/src/api/processor.rs
Pauline 28b1f9f0e3
Feature: Package API (#75) (i'm just going to merge this because the other branches are inactive)
* feat: Start work on package api

* feat: Browser Context Controller

* feat: Add packages to cluster metadata
feat: Change structure of Package

* 🐛 fix: format

* 🔨 feat: Add more functions wrapping around Modrinth

* 🔨 feat: Start working on browser frontend

* feat: BrowserPackage work + markdown support

* 🐛 fix: fmt

Signed-off-by: Pauline <git@ethanlibs.co>

* 🚧 wip: h

Signed-off-by: Pauline <git@ethanlibs.co>

* feat: Download button for packages for suitable clusters + tweaks

* 🚧 wip: markdown and stuff

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: some patches

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: remove react bloat

Signed-off-by: Pauline <git@ethanlibs.co>

* 🔨 chore(pkg/infer): try to reduce reused code

Signed-off-by: Pauline <git@ethanlibs.co>

* 🔨 chore: bump deps

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: markdown innerhtml

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: h

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: tweak

Signed-off-by: Pauline <git@ethanlibs.co>

* 🚧 wip: idk

Signed-off-by: Pauline <git@ethanlibs.co>

* fix: Gamemode compile error
chore: Add missing and remove unused libraries
feat: usePreventLeave hook
feat: ClusterOverview edit mode continues with navigation (assuming there was a navigation attempt) after pressing Yes or No for save

* feat: Add reload clusters button on home page

* feat: More information provided to BrowserPackage

* fix: Minor fixes (Navbar isActive, Markdown click prevention, Markdown list styling)

* 🐛 fix: h

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: highlighting

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: forge modern

Signed-off-by: Pauline <git@ethanlibs.co>

* 🔨 chore: bump deps

Signed-off-by: Pauline <git@ethanlibs.co>

* fix: Markdown-it issue + Added promptOpener hook for Markdown links

* feat: Made BrowserPackage sidebar sticky

* refactor: Package system (not yet in a working state)

* 🚧 wip: bump deps temp

Signed-off-by: Pauline <git@ethanlibs.co>

* feat: Added a package manager

* ✨ feature: start prisma work, but it doesnt break anything so we can keep it until its done. also fix some stuff

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: pushing

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: linting

Signed-off-by: Pauline <git@ethanlibs.co>

* ✨ feature: start ingress integration

Signed-off-by: Pauline <git@ethanlibs.co>

* feat: Package Manager should work now 👍

* fix: Package manager tracing spam

* feat: Added tauri commands for cluster packages
format: Auto formatted frontend + backend

* 🐛 fix: tmp

Signed-off-by: Pauline <git@ethanlibs.co>

* 🔨 chore: format

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: specta extension

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: github actions

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: alias

Signed-off-by: Pauline <git@ethanlibs.co>

* chore: Some tweaks and fixes

* chore: Rebase + gitignore bindings.ts

* chore: Remove bindings.ts

* 🐛 fix: migrate

Signed-off-by: Pauline <git@ethanlibs.co>

* 🚧 wip: not sure

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: finalize prisma init schema

Signed-off-by: Pauline <git@ethanlibs.co>

* 🔨 chore: format

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: bump deps

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: system deps

Signed-off-by: Pauline <git@ethanlibs.co>

* fix: solid-router navigation issue

* feat: Added new BrowserMain page

* feat: Tweaks + new package list view

* 🐛 fix: bump + format (todo: tauri2, etc)

Signed-off-by: Pauline <git@ethanlibs.co>

* 🐛 fix: devx (fixes #126)

Signed-off-by: Pauline <git@ethanlibs.co>

* 🔨 chore: migrate to consola

Signed-off-by: Pauline <git@ethanlibs.co>

---------

Signed-off-by: Pauline <git@ethanlibs.co>
Co-authored-by: LynithDev <61880709+LynithDev@users.noreply.github.com>
2024-08-31 16:23:24 -04:00

232 lines
6.4 KiB
Rust

//! Process management interface
pub use crate::store::{Cluster, InitHooks, JavaOptions, Memory, Resolution, Settings, State};
use crate::store::{ClusterPath, ProcessorChild};
use chrono::{DateTime, Utc};
use uuid::Uuid;
#[derive(serde::Serialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
pub struct DetailedProcess {
pub uuid: Uuid,
pub user: Option<Uuid>,
pub started_at: DateTime<Utc>,
pub pid: u32,
}
impl DetailedProcess {
pub async fn from_processor_child(process: &ProcessorChild) -> Self {
let pid = process.current_child.read().await.id().unwrap_or(0);
Self {
uuid: process.uuid,
user: process.user,
started_at: process.started_at,
pid,
}
}
}
/// get detailed processes by a [`ClusterPath`].
#[tracing::instrument]
pub async fn get_process_detailed_by_id(uuid: Uuid) -> crate::Result<DetailedProcess> {
let state = State::get().await?;
let processor = state.processor.read().await;
let child = processor
.get(uuid)
.ok_or(anyhow::anyhow!("process not found"))?;
let child = child.read().await;
let pid = child
.current_child
.read()
.await
.id()
.ok_or(anyhow::anyhow!("process not found"))?;
Ok(DetailedProcess {
uuid,
user: child.user,
started_at: child.started_at,
pid,
})
}
/// get detailed processes by a [`ClusterPath`].
#[tracing::instrument]
pub async fn get_processes_detailed_by_path(
path: ClusterPath,
) -> crate::Result<Vec<DetailedProcess>> {
let state = State::get().await?;
let processor = state.processor.read().await;
let uuids = processor.running_cluster(path).await?;
let mut processes = Vec::new();
for uuid in uuids {
let child = processor
.get(uuid)
.ok_or(anyhow::anyhow!("process not found"))?;
let child = child.read().await;
let pid = child
.current_child
.read()
.await
.id()
.ok_or(anyhow::anyhow!("process not found"))?;
processes.push(DetailedProcess {
uuid,
user: child.user,
started_at: child.started_at,
pid,
});
}
Ok(processes)
}
/// check whether or not a process has completed by its [`Uuid`].
#[tracing::instrument]
pub async fn uuid_is_finished(uuid: Uuid) -> crate::Result<bool> {
Ok(uuid_exit_status(uuid).await?.is_some())
}
/// get the user from a processor by its [`Uuid`].
#[tracing::instrument]
pub async fn get_user_by_process(uuid: Uuid) -> crate::Result<Option<Uuid>> {
let state = State::get().await?;
let processor = state.processor.read().await;
if let Some(processor) = processor.get(uuid) {
Ok(processor.read().await.user)
} else {
Err(anyhow::anyhow!("process not found").into())
}
}
/// get the user from a processor by its [`Uuid`].
#[tracing::instrument]
pub async fn get_process_started_at(uuid: Uuid) -> crate::Result<DateTime<Utc>> {
let state = State::get().await?;
let processor = state.processor.read().await;
if let Some(processor) = processor.get(uuid) {
Ok(processor.read().await.started_at)
} else {
Err(anyhow::anyhow!("process not found").into())
}
}
/// check the exit status of a process by its [`Uuid`].
#[tracing::instrument]
pub async fn uuid_exit_status(uuid: Uuid) -> crate::Result<Option<i32>> {
let state = State::get().await?;
let processor = state.processor.read().await;
processor.exit_status(uuid).await
}
/// get all process [`Uuid`]s.
#[tracing::instrument]
pub async fn get_uuids() -> crate::Result<Vec<Uuid>> {
let state = State::get().await?;
let processor = state.processor.read().await;
Ok(processor.keys())
}
/// get all running process [`Uuid`]s.
#[tracing::instrument]
pub async fn get_running() -> crate::Result<Vec<Uuid>> {
let state = State::get().await?;
let processor = state.processor.read().await;
processor.running().await
}
/// get all running process' [`ClusterPath`]s.
#[tracing::instrument]
pub async fn get_running_cluster_paths() -> crate::Result<Vec<ClusterPath>> {
let state = State::get().await?;
let processor = state.processor.read().await;
processor.running_cluster_paths().await
}
/// get all running process' [`Cluster`]s.
#[tracing::instrument]
pub async fn get_running_clusters() -> crate::Result<Vec<Cluster>> {
let state = State::get().await?;
let processor = state.processor.read().await;
processor.running_clusters().await
}
/// check if a cluster is running by its [`Uuid`].
#[tracing::instrument]
pub async fn is_cluster_running(uuid: Uuid) -> crate::Result<bool> {
let clusters = get_running_clusters().await?;
Ok(clusters.iter().any(|cluster| cluster.uuid == uuid))
}
/// get all processes by a [`ClusterPath`].
#[tracing::instrument]
pub async fn get_uuids_by_cluster_path(cluster_path: ClusterPath) -> crate::Result<Vec<Uuid>> {
let state = State::get().await?;
let processor = state.processor.read().await;
processor.running_cluster(cluster_path).await
}
/// kill an existing and running process by its [`Uuid`]
#[tracing::instrument]
pub async fn kill_by_uuid(uuid: Uuid) -> crate::Result<()> {
let state = State::get().await?;
let processor = state.processor.read().await;
if let Some(process) = processor.get(uuid) {
let mut process = process.write().await;
kill(&mut process).await
} else {
Ok(())
}
}
/// wait for a child process to finish running its manager by its [`Uuid`].
#[tracing::instrument]
pub async fn wait_for_by_uuid(uuid: Uuid) -> crate::Result<()> {
let state = State::get().await?;
let processor = state.processor.read().await;
if let Some(process) = processor.get(uuid) {
let mut process = process.write().await;
wait_for(&mut process).await
} else {
Ok(())
}
}
/// kill an existing and running process
#[tracing::instrument(skip(process))]
pub async fn kill(process: &mut ProcessorChild) -> crate::Result<()> {
process.current_child.write().await.kill().await?;
Ok(())
}
/// wait for a child process to finish running its manager
#[tracing::instrument(skip(process))]
pub async fn wait_for(process: &mut ProcessorChild) -> crate::Result<()> {
process
.manager
.take()
.ok_or_else(|| anyhow::anyhow!("manager already completed for process {}", process.uuid))?
.await?
.map_err(|err| anyhow::anyhow!("failed to run minecraft: {err}"))?;
Ok(())
}
/// get process pid by its [`Uuid`].
#[tracing::instrument]
pub async fn get_pid_by_uuid(uuid: Uuid) -> crate::Result<u32> {
let state = State::get().await?;
let processor = state.processor.read().await;
Ok(processor
.get(uuid)
.ok_or(anyhow::anyhow!("process not found"))?
.read()
.await
.current_child
.read()
.await
.id()
.ok_or(anyhow::anyhow!("process not found"))?)
}