pub struct JobManager { /* private fields */ }Expand description
Manager for background jobs.
Implementations§
Source§impl JobManager
impl JobManager
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new job manager.
On construction, best-effort prunes stale job output files left by previously crashed kaish processes. All errors are intentionally ignored — startup cleanup is opportunistic and must never prevent the manager from being created (silent-fallback rule: the only case where silent is correct is read-only / cleanup-only paths with no data loss risk).
§Scoping decision
All sessions share a single /tmp/kaish/jobs/ directory. Filenames embed
the OS PID that wrote them (session_S_job_J.PID.txt). Files from the
current process are never touched here — only files whose embedded PID
refers to a dead process are removed. On Linux we check /proc/{pid} for
existence; on other platforms we skip the prune rather than guess.
Sourcepub fn set_persist_output_files(&self, on: bool)
pub fn set_persist_output_files(&self, on: bool)
Toggle whether completed jobs persist their output to a host temp file.
Disable this for a hermetic / read-only kernel: the host write in
Job::write_output_file uses std::fs directly and so bypasses the
VFS (and any read-only mount). Live output stays available in-memory via
the VFS streams (/v/jobs/{id}/stdout), so nothing is lost in-process.
Must be set before jobs are spawned — the flag is stamped onto each job at registration time, not consulted at completion.
Sourcepub fn persist_output_files(&self) -> bool
pub fn persist_output_files(&self) -> bool
Whether completed jobs persist their output to a host temp file.
Sourcepub async fn spawn<F>(&self, command: String, future: F) -> JobId
pub async fn spawn<F>(&self, command: String, future: F) -> JobId
Spawn a new background job from a future.
The job is inserted into the map synchronously before returning,
guaranteeing it’s immediately queryable via exists() or get().
Sourcepub async fn register(&self, command: String, rx: Receiver<ExecResult>) -> JobId
pub async fn register(&self, command: String, rx: Receiver<ExecResult>) -> JobId
Spawn a job that’s already running and communicate via channel.
Sourcepub async fn register_with_streams(
&self,
command: String,
rx: Receiver<ExecResult>,
stdout: Arc<BoundedStream>,
stderr: Arc<BoundedStream>,
) -> JobId
pub async fn register_with_streams( &self, command: String, rx: Receiver<ExecResult>, stdout: Arc<BoundedStream>, stderr: Arc<BoundedStream>, ) -> JobId
Register a job with attached output streams.
The streams provide live access to job output via /v/jobs/{id}/stdout and /stderr.
Sourcepub async fn wait(&self, id: JobId) -> Option<ExecResult>
pub async fn wait(&self, id: JobId) -> Option<ExecResult>
Wait for a specific job to complete.
The job’s pending awaitable (its task handle or result channel) is taken
out of the map under the lock, then the lock is released before
awaiting completion. Holding the jobs mutex across the await would
block every other job operation (spawn/register/list/status/kill) for the
whole duration of the job — so a nested & started under a parked
wait %N would deadlock. The lock is re-acquired only to finalize
(persist output, cache the result).
Sourcepub async fn wait_all(&self) -> Vec<(JobId, ExecResult)>
pub async fn wait_all(&self) -> Vec<(JobId, ExecResult)>
Wait for all jobs to complete, returning results in completion order.
Sourcepub async fn running_count(&self) -> usize
pub async fn running_count(&self) -> usize
Get the number of running jobs.
Sourcepub async fn get_command(&self, id: JobId) -> Option<String>
pub async fn get_command(&self, id: JobId) -> Option<String>
Get the command string for a job.
Sourcepub async fn get_status_string(&self, id: JobId) -> Option<String>
pub async fn get_status_string(&self, id: JobId) -> Option<String>
Get the status string for a job (for /v/jobs/{id}/status).
Sourcepub async fn read_stdout(&self, id: JobId) -> Option<Vec<u8>>
pub async fn read_stdout(&self, id: JobId) -> Option<Vec<u8>>
Read stdout stream content for a job.
Returns None if the job doesn’t exist or has no attached stream.
Sourcepub async fn read_stderr(&self, id: JobId) -> Option<Vec<u8>>
pub async fn read_stderr(&self, id: JobId) -> Option<Vec<u8>>
Read stderr stream content for a job.
Returns None if the job doesn’t exist or has no attached stream.
Sourcepub async fn register_stopped(
&self,
command: String,
pid: u32,
pgid: u32,
) -> JobId
pub async fn register_stopped( &self, command: String, pid: u32, pgid: u32, ) -> JobId
Register a stopped job (from Ctrl-Z on a foreground process).
Sourcepub async fn stop_job(&self, id: JobId, pid: u32, pgid: u32)
pub async fn stop_job(&self, id: JobId, pid: u32, pgid: u32)
Mark a job as stopped with its process info.
Sourcepub async fn resume_job(&self, id: JobId)
pub async fn resume_job(&self, id: JobId)
Mark a stopped job as resumed.
Sourcepub async fn last_stopped(&self) -> Option<JobId>
pub async fn last_stopped(&self) -> Option<JobId>
Get the most recently stopped job.
Sourcepub async fn get_process_info(&self, id: JobId) -> Option<(u32, u32)>
pub async fn get_process_info(&self, id: JobId) -> Option<(u32, u32)>
Get process info (pid, pgid) for a job.
Sourcepub async fn set_cancel_token(&self, id: JobId, token: CancellationToken)
pub async fn set_cancel_token(&self, id: JobId, token: CancellationToken)
Record the cancellation token of the fork running a background job, so
kill %N can stop the job even when it has no OS process group of its
own (e.g. a pure builtin like sleep &).
Sourcepub async fn cancel(&self, id: JobId) -> bool
pub async fn cancel(&self, id: JobId) -> bool
Cancel a job by its token. Returns true if a token was recorded and
cancelled. The cancellation cascade stops in-process builtin futures and
SIGTERM→SIGKILLs any external children’s process groups.
Sourcepub async fn add_pgid(&self, id: JobId, pgid: u32)
pub async fn add_pgid(&self, id: JobId, pgid: u32)
Record a process group spawned while running a background job. Lets
kill -<sig> %N deliver an arbitrary signal directly to the real
processes. Deduplicated (a job may spawn several externals).