workdir: centralize workspace inventory contract
This commit is contained in:
@@ -92,12 +92,11 @@ pub struct WorkingDirectoryRepository {
|
||||
pub selector: Option<RepositorySelector>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MaterializerKind {
|
||||
#[default]
|
||||
LocalGitWorktree,
|
||||
}
|
||||
pub use workdir::workspace::{
|
||||
MaterializerKind, WorkingDirectoryCleanupTarget, WorkingDirectoryCurrentObservation,
|
||||
WorkingDirectoryOccupancy, WorkingDirectoryProvenance, WorkingDirectoryStatusKind,
|
||||
WorkingDirectorySummary,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WorkingDirectoryRequest {
|
||||
@@ -117,59 +116,6 @@ pub struct WorkingDirectoryClaim {
|
||||
pub relative_cwd: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WorkingDirectoryStatusKind {
|
||||
Active,
|
||||
CleanupPending,
|
||||
Corrupted,
|
||||
NotFound,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WorkingDirectoryCleanupTarget {
|
||||
pub kind: String,
|
||||
pub working_directory_id: String,
|
||||
pub repository_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WorkingDirectoryOccupancy {
|
||||
#[serde(flatten)]
|
||||
pub worker: RuntimeWorkerRef,
|
||||
pub display_name: String,
|
||||
pub linked_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WorkingDirectorySummary {
|
||||
pub working_directory_id: String,
|
||||
pub repository_id: String,
|
||||
/// Selector used to create this Workdir, retained as immutable materialization evidence.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub creation_selector: Option<String>,
|
||||
/// Provider-specific immutable ref resolved when this Workdir was created.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub creation_ref: Option<String>,
|
||||
/// Selector currently observed from the materialized Workdir, when one exists.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub current_selector: Option<String>,
|
||||
/// Provider-specific immutable ref currently observed from the materialized Workdir.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub current_ref: Option<String>,
|
||||
pub materializer_kind: MaterializerKind,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub cleanup_target: Option<WorkingDirectoryCleanupTarget>,
|
||||
pub status: WorkingDirectoryStatusKind,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub cleanliness: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub primary_worker_id: Option<WorkerId>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub occupied_by: Option<WorkingDirectoryOccupancy>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WorkingDirectoryStatus {
|
||||
pub summary: WorkingDirectorySummary,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
pub use workdir::workspace::RuntimeWorkerRef;
|
||||
|
||||
/// Runtime-local Worker identity.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
@@ -30,29 +31,16 @@ impl fmt::Display for WorkerId {
|
||||
}
|
||||
}
|
||||
|
||||
/// Backend-visible Worker identity, namespaced by the Runtime that owns the Worker record.
|
||||
///
|
||||
/// This is intentionally distinct from [`WorkerRef`], which is meaningful only inside one
|
||||
/// Runtime. Do not flatten this reference into a concatenated string for authority decisions.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct RuntimeWorkerRef {
|
||||
pub runtime_id: String,
|
||||
pub worker_id: String,
|
||||
}
|
||||
/// Convert an opaque Workspace Worker reference only at the Runtime-local boundary.
|
||||
impl TryFrom<&RuntimeWorkerRef> for WorkerRef {
|
||||
type Error = std::num::ParseIntError;
|
||||
|
||||
impl RuntimeWorkerRef {
|
||||
pub fn new(runtime_id: impl Into<String>, worker_id: impl Into<String>) -> Self {
|
||||
Self {
|
||||
runtime_id: runtime_id.into(),
|
||||
worker_id: worker_id.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_worker_ref(&self) -> Result<WorkerRef, std::num::ParseIntError> {
|
||||
self.worker_id
|
||||
fn try_from(value: &RuntimeWorkerRef) -> Result<Self, Self::Error> {
|
||||
value
|
||||
.worker_id
|
||||
.parse::<u64>()
|
||||
.map(WorkerId::new)
|
||||
.map(WorkerRef::new)
|
||||
.map(Self::new)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +66,7 @@ mod tests {
|
||||
assert_eq!(worker.runtime_id, "arcadia");
|
||||
assert_eq!(worker.worker_id, "30");
|
||||
assert_eq!(
|
||||
worker.local_worker_ref().unwrap(),
|
||||
WorkerRef::try_from(&worker).unwrap(),
|
||||
WorkerRef::new(WorkerId::new(30))
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -90,6 +78,6 @@ mod tests {
|
||||
#[test]
|
||||
fn runtime_worker_ref_does_not_treat_composite_text_as_local_worker_id() {
|
||||
let worker = RuntimeWorkerRef::new("arcadia", "embedded-worker-runtime-5");
|
||||
assert!(worker.local_worker_ref().is_err());
|
||||
assert!(WorkerRef::try_from(&worker).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,8 +467,9 @@ impl Runtime {
|
||||
mut status: CatalogWorkingDirectoryStatus,
|
||||
) -> Result<CatalogWorkingDirectoryStatus, RuntimeError> {
|
||||
let state = self.lock()?;
|
||||
status.summary.primary_worker_id =
|
||||
state.primary_worker_id_for_workdir(status.summary.working_directory_id.as_str());
|
||||
status.summary.primary_worker_id = state
|
||||
.primary_worker_id_for_workdir(status.summary.working_directory_id.as_str())
|
||||
.map(|worker_id| worker_id.as_u64());
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ impl WorkerObservationProvider for RuntimeGrantedWorkerObservationProvider {
|
||||
if grant.runtime_id != self.runtime_id {
|
||||
continue;
|
||||
}
|
||||
let Ok(worker_ref) = grant.local_worker_ref() else {
|
||||
let Ok(worker_ref) = WorkerRef::try_from(grant) else {
|
||||
continue;
|
||||
};
|
||||
let Some((workspace_id, state, _)) = self.hub.get(&worker_ref) else {
|
||||
@@ -192,9 +192,8 @@ impl WorkerObservationProvider for RuntimeGrantedWorkerObservationProvider {
|
||||
if !self.grants.contains(&grant) || runtime_id != &self.runtime_id {
|
||||
return Err(WorkerObservationError::NotFound);
|
||||
}
|
||||
let worker_ref = grant
|
||||
.local_worker_ref()
|
||||
.map_err(|_| WorkerObservationError::NotFound)?;
|
||||
let worker_ref =
|
||||
WorkerRef::try_from(&grant).map_err(|_| WorkerObservationError::NotFound)?;
|
||||
let (workspace_id, _, sink) = self
|
||||
.hub
|
||||
.get(&worker_ref)
|
||||
|
||||
Reference in New Issue
Block a user