Skip to content

Commit 10f5dd8

Browse files
authored
Attempt to bootstrap the db on connect (#2029)
Fixes #2024 Whenever `db.connect` is called, we will try to bootstrap the db if required
2 parents dd24074 + f2f0eda commit 10f5dd8

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

libsql/src/database.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,18 @@ impl Database {
682682
};
683683
use tokio::sync::Mutex;
684684

685+
let _ = tokio::task::block_in_place(move || {
686+
let rt = tokio::runtime::Builder::new_current_thread()
687+
.enable_all()
688+
.build()
689+
.unwrap();
690+
rt.block_on(async {
691+
// we will ignore if any errors occurred during the bootstrapping the db,
692+
// because the client could be offline when trying to connect.
693+
let _ = db.bootstrap_db().await;
694+
})
695+
});
696+
685697
let local = db.connect()?;
686698

687699
if *remote_writes {

libsql/src/local/database.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,21 @@ impl Database {
465465
/// Sync WAL frames to remote.
466466
pub async fn sync_offline(&self) -> Result<crate::database::Replicated> {
467467
let mut sync_ctx = self.sync_ctx.as_ref().unwrap().lock().await;
468+
// it is important we call `bootstrap` before we `sync`. Because sync uses a connection
469+
// to the db and during bootstrap we replace the sqlite db file. This can lead to
470+
// inconsistencies and data corruption.
468471
crate::sync::bootstrap_db(&mut sync_ctx).await?;
469472
let conn = self.connect()?;
470473
crate::sync::sync_offline(&mut sync_ctx, &conn).await
471474
}
472475

476+
#[cfg(feature = "sync")]
477+
/// Brings the .db file from server, if required.
478+
pub async fn bootstrap_db(&self) -> Result<()> {
479+
let mut sync_ctx = self.sync_ctx.as_ref().unwrap().lock().await;
480+
crate::sync::bootstrap_db(&mut sync_ctx).await
481+
}
482+
473483
pub(crate) fn path(&self) -> &str {
474484
&self.db_path
475485
}

libsql/src/sync.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,8 @@ async fn atomic_write<P: AsRef<Path>>(path: P, data: &[u8]) -> Result<()> {
686686

687687
/// bootstrap_db brings the .db file from remote, if required. If the .db file already exists, then
688688
/// it does nothing. Calling this function multiple times is safe.
689+
/// However, make sure there are no existing active connections to the db file as this method can
690+
/// replace it
689691
pub async fn bootstrap_db(sync_ctx: &mut SyncContext) -> Result<()> {
690692
// todo: we are checking with the remote server only during initialisation. ideally,
691693
// we need to do this when we notice a large gap in generations, when bootstrapping is cheaper

0 commit comments

Comments
 (0)