Skip to content

Commit cfb8e23

Browse files
committed
when we detect a concurrent migration, retry 3 minutes later instead of failing
1 parent cfefd1b commit cfb8e23

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

examples/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

linera-sdk/tests/fixtures/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

linera-storage/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ linera-views.workspace = true
4747
papaya.workspace = true
4848
prometheus.workspace = true
4949
serde.workspace = true
50+
tokio.workspace = true
5051
tracing.workspace = true
5152

5253
[dev-dependencies]

linera-storage/src/migration.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use linera_views::{
1111
ViewError,
1212
};
1313
use serde::{Deserialize, Serialize};
14+
use tokio::time::Duration;
1415

1516
use crate::{
1617
db_storage::{
@@ -29,6 +30,9 @@ enum SchemaVersion {
2930
Version1,
3031
}
3132

33+
/// How long we should wait before retrying when we detect another migration in progress.
34+
const MIGRATION_WAIT_BEFORE_RETRY_MIN: u64 = 3;
35+
3236
const UNUSED_EMPTY_KEY: &[u8] = &[];
3337
// We choose the ordering of the variants in `BaseKey` and `RootKey` so that
3438
// the root keys corresponding to `ChainState` and `BlockExporter` remain the
@@ -154,13 +158,26 @@ where
154158
}
155159

156160
pub async fn migrate_if_needed(&self) -> Result<(), ViewError> {
157-
match self.get_storage_state().await? {
158-
Some(SchemaVersion::Version0) => self.migrate_v0_to_v1().await,
159-
Some(SchemaVersion::Version1) => Ok(()),
160-
None => {
161-
// Need to initialize the DB, not migrate it.
162-
Ok(())
161+
loop {
162+
if matches!(
163+
self.get_storage_state().await?,
164+
None | Some(SchemaVersion::Version1)
165+
) {
166+
// Nothing to do.
167+
return Ok(());
168+
}
169+
let result = self.migrate_v0_to_v1().await;
170+
if let Err(ViewError::MissingEntries) = result {
171+
tracing::warn!(
172+
"It looks like a migration is already in progress on this database. \
173+
I will wait for {:?} minutes and retry.",
174+
MIGRATION_WAIT_BEFORE_RETRY_MIN
175+
);
176+
// Duration::from_mins is not yet stable for tokio 1.36.
177+
tokio::time::sleep(Duration::from_secs(MIGRATION_WAIT_BEFORE_RETRY_MIN * 60)).await;
178+
continue;
163179
}
180+
return result;
164181
}
165182
}
166183

0 commit comments

Comments
 (0)