flow: own worker flow state in runtime sessions

This commit is contained in:
2026-08-09 18:04:32 +09:00
parent c0532fda4e
commit 068ba9afa5
46 changed files with 5112 additions and 76 deletions
+100
View File
@@ -11,6 +11,7 @@ mod operation;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
@@ -158,6 +159,105 @@ pub trait WorkdirSession: std::fmt::Debug + Send + Sync {
pub type WorkdirSessionHandle = Arc<dyn WorkdirSession>;
/// Ephemeral least-authority view over an existing Workdir session.
///
/// The wrapper exposes only stat/read/list/glob/grep and never forwards write,
/// edit, command, or close authority to the underlying Worker session. Closing
/// the wrapper is terminal for the view but deliberately leaves the owner's
/// source session open.
#[derive(Debug)]
pub struct ReadOnlyWorkdirSession {
source: WorkdirSessionHandle,
closed: AtomicBool,
}
impl ReadOnlyWorkdirSession {
pub fn new(source: WorkdirSessionHandle) -> Self {
Self {
source,
closed: AtomicBool::new(false),
}
}
fn ensure_open(&self) -> Result<(), WorkdirError> {
if self.closed.load(Ordering::Acquire) {
Err(WorkdirError::Unavailable(
"read-only Workdir session is closed".to_string(),
))
} else {
Ok(())
}
}
}
#[async_trait]
impl WorkdirSession for ReadOnlyWorkdirSession {
fn workdir(&self) -> &Workdir {
self.source.workdir()
}
fn capabilities(&self) -> WorkdirSessionCapabilities {
WorkdirSessionCapabilities::READ_ONLY
}
async fn stat(&self, request: StatRequest) -> Result<StatResult, WorkdirError> {
self.ensure_open()?;
self.source.stat(request).await
}
async fn read(&self, request: ReadRequest) -> Result<ReadResult, WorkdirError> {
self.ensure_open()?;
self.source.read(request).await
}
async fn write(&self, _request: WriteRequest) -> Result<WriteResult, WorkdirError> {
Err(WorkdirError::Unsupported(WorkdirSessionCapability::Write))
}
async fn edit(&self, _request: EditRequest) -> Result<EditResult, WorkdirError> {
Err(WorkdirError::Unsupported(WorkdirSessionCapability::Edit))
}
async fn list(&self, request: ListRequest) -> Result<ListResult, WorkdirError> {
self.ensure_open()?;
self.source.list(request).await
}
async fn glob(&self, request: GlobRequest) -> Result<GlobResult, WorkdirError> {
self.ensure_open()?;
self.source.glob(request).await
}
async fn grep(&self, request: GrepRequest) -> Result<GrepResult, WorkdirError> {
self.ensure_open()?;
self.source.grep(request).await
}
async fn start_command(&self, _request: CommandRequest) -> Result<CommandHandle, WorkdirError> {
Err(WorkdirError::Unsupported(WorkdirSessionCapability::Command))
}
async fn command_status(&self, _handle: CommandHandle) -> Result<CommandStatus, WorkdirError> {
Err(WorkdirError::Unsupported(WorkdirSessionCapability::Command))
}
async fn command_output(
&self,
_request: CommandOutputRequest,
) -> Result<CommandOutput, WorkdirError> {
Err(WorkdirError::Unsupported(WorkdirSessionCapability::Command))
}
async fn cancel_command(&self, _handle: CommandHandle) -> Result<(), WorkdirError> {
Err(WorkdirError::Unsupported(WorkdirSessionCapability::Command))
}
async fn close(&self) -> Result<(), WorkdirError> {
self.closed.store(true, Ordering::Release);
Ok(())
}
}
#[derive(Debug, thiserror::Error)]
pub enum WorkdirError {
#[error("Workdir session does not support {0:?}")]