Skip to content

Commit 571f586

Browse files
committed
dataflow-state: Handle non-existent deployment dirs
At process start up, Readyset will clean out the tmp/working dir, in case the process crashed on a previous run and we need to delete temp files. If the `working_dir` already exists by the time the `clean_working_dir()` function is invoked, then everything is fine. If the directory does not exist, then the call to `Path::canonicalize()` will fail. This problem does not exist in standalone, as the Standalone Authority is created (and it's storage directories) much earlier than we attempt to clean out the working dir. This is not the case in adapter/server operation, which is where this was failing. The fix is to simply not try to delete or canonicalize the working directory path if the directory does not exist. Release-Note-Core: Fix a bug in distributed readyset where readyset-server will fail on startup due to a missing working_dir. Change-Id: Ibe7b0511d285b224a36ce7568673105926f1c354 Reviewed-on: https://gerrit.readyset.name/c/readyset/+/7920 Tested-by: Buildkite CI Reviewed-by: Johnathan Davis <jcd@readyset.io>
1 parent 7bed7c9 commit 571f586

File tree

1 file changed

+15
-15
lines changed
  • dataflow-state/src/persistent_state

1 file changed

+15
-15
lines changed

dataflow-state/src/persistent_state/mod.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ const INDEX_BATCH_SIZE: usize = 10_000;
131131
/// to prevent any further disk use leakage. This function should be executed once,
132132
/// preferably at startup.
133133
pub fn clean_working_dir(params: &PersistenceParameters) -> Result<()> {
134-
let working_dir = params.derive_working_dir_base()?;
135-
134+
let working_dir = params.working_dir_base();
136135
if working_dir.is_dir() {
137136
debug!("deleting any prior working files from {:?}", &working_dir);
138137
fs::remove_dir_all(working_dir)?
@@ -325,17 +324,17 @@ impl PersistenceParameters {
325324
}
326325
}
327326

328-
fn derive_working_dir_base(&self) -> Result<PathBuf> {
329-
// use what the operator passed in, or default to the storage_dir
327+
fn storage_dir(&self) -> PathBuf {
328+
self.storage_dir.clone().unwrap_or_else(|| ".".into())
329+
}
330+
331+
fn working_dir_base(&self) -> PathBuf {
330332
let base_dir = match &self.working_temp_dir {
331333
Some(s) => s.clone(),
332-
None => self.storage_dir.clone().unwrap_or_else(|| ".".into()),
334+
None => self.storage_dir(),
333335
};
334-
// canonicalize the path else `tempdir` might get confused with a relative path.
335-
let base_dir = base_dir.canonicalize()?;
336336

337-
// use a "parent" directory to house all the various tmp rocksdb instances
338-
Ok(base_dir.join(WORKING_DIR))
337+
base_dir.join(WORKING_DIR)
339338
}
340339
}
341340

@@ -1477,22 +1476,23 @@ impl PersistentState {
14771476

14781477
let (tmpdir, full_path) = match params.mode {
14791478
DurabilityMode::Permanent => {
1480-
let mut path = params.storage_dir.clone().unwrap_or_else(|| ".".into());
1479+
let mut path = params.storage_dir();
14811480
if !path.is_dir() {
14821481
fs::create_dir_all(&path)?;
14831482
}
14841483
path.push(&name);
14851484

14861485
(None, path)
14871486
}
1488-
_ => {
1489-
let working_dir = params.derive_working_dir_base()?;
1490-
if !working_dir.is_dir() {
1487+
DurabilityMode::DeleteOnExit | DurabilityMode::MemoryOnly => {
1488+
let working_dir = params.working_dir_base();
1489+
if !working_dir.exists() {
14911490
fs::create_dir_all(&working_dir)?;
14921491
}
1492+
let canonical_dir = working_dir.canonicalize()?;
14931493

1494-
// create the subdirectory specific to this node
1495-
let tempdir = Builder::new().prefix(&name).tempdir_in(working_dir)?;
1494+
// create the temp subdirectory specific to this node
1495+
let tempdir = Builder::new().prefix(&name).tempdir_in(canonical_dir)?;
14961496
let path = tempdir.path().to_path_buf();
14971497

14981498
(Some(tempdir), path)

0 commit comments

Comments
 (0)