Skip to content

Commit 4a5f373

Browse files
authored
Merge pull request #1830 from tursodatabase/lucio/cache-server-frame
libsql: add `durable_frame_num` caching and metadata file
2 parents 49e6393 + 11cce47 commit 4a5f373

File tree

10 files changed

+687
-38
lines changed

10 files changed

+687
-38
lines changed

Cargo.lock

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

libsql/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ fallible-iterator = { version = "0.3", optional = true }
4343
libsql_replication = { version = "0.6", path = "../libsql-replication", optional = true }
4444
async-stream = { version = "0.3.5", optional = true }
4545

46+
crc32fast = { version = "1", optional = true }
47+
chrono = { version = "0.4", optional = true }
48+
4649
[dev-dependencies]
4750
criterion = { version = "0.5", features = ["html_reports", "async", "async_futures", "async_tokio"] }
4851
pprof = { version = "0.12.1", features = ["criterion", "flamegraph"] }
@@ -105,6 +108,10 @@ sync = [
105108
"dep:tokio",
106109
"dep:futures",
107110
"dep:serde_json",
111+
"dep:crc32fast",
112+
"dep:chrono",
113+
"dep:uuid",
114+
"tokio/fs"
108115
]
109116
hrana = [
110117
"parser",

libsql/src/database.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ cfg_core! {
3434
}
3535

3636
cfg_replication_or_sync! {
37+
3738
pub type FrameNo = u64;
3839

3940
#[derive(Debug)]
41+
// TODO(lucio): remove this once we use these fields in our sync code
42+
#[allow(dead_code)]
4043
pub struct Replicated {
4144
pub(crate) frame_no: Option<FrameNo>,
4245
pub(crate) frames_synced: usize,
@@ -47,12 +50,16 @@ cfg_replication_or_sync! {
4750
/// where in the log you might be. Beware that this value can be reset to a lower value by the
4851
/// server in certain situations. Please use `frames_synced` if you want to track the amount of
4952
/// work a sync has done.
53+
// TODO(lucio): remove this once we use these fields in our sync code
54+
#[allow(dead_code)]
5055
pub fn frame_no(&self) -> Option<FrameNo> {
5156
self.frame_no
5257
}
5358

5459
/// The count of frames synced during this call of `sync`. A frame is a 4kB frame from the
5560
/// libsql write ahead log.
61+
// TODO(lucio): remove this once we use these fields in our sync code
62+
#[allow(dead_code)]
5663
pub fn frames_synced(&self) -> usize {
5764
self.frames_synced
5865
}

libsql/src/database/builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl Builder<()> {
119119
}
120120
}
121121

122-
cfg_replication_or_remote! {
122+
cfg_replication_or_remote_or_sync! {
123123
/// Remote configuration type used in [`Builder`].
124124
pub struct Remote {
125125
url: String,
@@ -505,7 +505,7 @@ cfg_remote! {
505505
}
506506
}
507507

508-
cfg_replication_or_remote! {
508+
cfg_replication_or_remote_or_sync! {
509509
impl Remote {
510510
fn connector<C>(mut self, connector: C) -> Remote
511511
where

libsql/src/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ pub enum Error {
5555
TransactionalBatchError(String),
5656
#[error("Invalid blob size, expected {0}")]
5757
InvalidBlobSize(usize),
58+
#[error("sync error: {0}")]
59+
Sync(crate::BoxError),
5860
}
5961

6062
#[cfg(feature = "hrana")]
@@ -64,6 +66,13 @@ impl From<crate::hrana::HranaError> for Error {
6466
}
6567
}
6668

69+
#[cfg(feature = "sync")]
70+
impl From<crate::sync::SyncError> for Error {
71+
fn from(e: crate::sync::SyncError) -> Self {
72+
Error::Sync(e.into())
73+
}
74+
}
75+
6776
impl From<std::convert::Infallible> for Error {
6877
fn from(_: std::convert::Infallible) -> Self {
6978
unreachable!()

libsql/src/local/database.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,11 @@ impl Database {
144144
endpoint
145145
};
146146
let mut db = Database::open(&db_path, flags)?;
147-
db.sync_ctx = Some(tokio::sync::Mutex::new(SyncContext::new(
148-
connector,
149-
endpoint,
150-
Some(auth_token),
151-
)));
147+
148+
let sync_ctx =
149+
SyncContext::new(connector, db_path.into(), endpoint, Some(auth_token)).await?;
150+
db.sync_ctx = Some(tokio::sync::Mutex::new(sync_ctx));
151+
152152
Ok(db)
153153
}
154154

@@ -388,7 +388,7 @@ impl Database {
388388
#[cfg(feature = "sync")]
389389
/// Push WAL frames to remote.
390390
pub async fn push(&self) -> Result<crate::database::Replicated> {
391-
let sync_ctx = self.sync_ctx.as_ref().unwrap().lock().await;
391+
let mut sync_ctx = self.sync_ctx.as_ref().unwrap().lock().await;
392392
let conn = self.connect()?;
393393

394394
let page_size = {
@@ -402,7 +402,7 @@ impl Database {
402402

403403
let max_frame_no = conn.wal_frame_count();
404404

405-
let generation = 1; // TODO: Probe from WAL.
405+
let generation = sync_ctx.generation(); // TODO: Probe from WAL.
406406
let start_frame_no = sync_ctx.durable_frame_num() + 1;
407407
let end_frame_no = max_frame_no;
408408

@@ -423,6 +423,10 @@ impl Database {
423423
frame_no += 1;
424424
}
425425

426+
sync_ctx.write_metadata().await?;
427+
428+
// TODO(lucio): this can underflow if the server previously returned a higher max_frame_no
429+
// than what we have stored here.
426430
let frame_count = end_frame_no - start_frame_no + 1;
427431
Ok(crate::database::Replicated {
428432
frame_no: None,

libsql/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ macro_rules! cfg_core {
1010
}
1111
}
1212

13-
macro_rules! cfg_replication_or_remote {
13+
macro_rules! cfg_replication_or_remote_or_sync {
1414
($($item:item)*) => {
1515
$(
1616
#[cfg(any(feature = "replication", feature = "sync", feature = "remote"))]

0 commit comments

Comments
 (0)