Repository: libsql/libsql
File: libsql/src/database/builder.rs (Rust)

Code before:
            if let Some(sync_interval) = sync_interval {
                let (cancel_tx, mut cancel_rx) = tokio::sync::oneshot::channel::<()>();

                let sync_span = tracing::debug_span!("sync_interval");
                let _enter = sync_span.enter();

                let sync_ctx = db.sync_ctx.as_ref().unwrap().clone();
                {
                    let mut ctx = sync_ctx.lock().await;
                    crate::sync::bootstrap_db(&mut ctx).await?;
                    tracing::debug!("finished bootstrap with sync interval");
                }

                // db.connect creates a local db file, so it is important that we always call
                // `bootstrap_db` (for synced dbs) before calling connect. Otherwise, the sync
                // protocol skips calling `export` endpoint causing slowdown in initial bootstrap.
                let conn = db.connect()?;

                tokio::spawn(
                    async move {
                        let mut interval = tokio::time::interval(sync_interval);

                        loop {
                            tracing::info!("trying to sync");

                            interval.tick().await;

                            let mut ctx = sync_ctx.lock().await;

                            if remote_writes {
                                tokio::select! {
                                    _ = &mut cancel_rx => break,
                                    result = crate::sync::try_pull(&mut ctx, &conn) => {
                                        if let Err(e) = result {
                                            tracing::error!("sync error: {}", e);
                                        }
                                    }
                                }
                            } else {
                                tokio::select! {
                                    _ = &mut cancel_rx => break,
                                    result = crate::sync::sync_offline(&mut ctx, &conn) => {
                                        if let Err(e) = result {
                                            tracing::error!("sync error: {}", e);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    .instrument(tracing::debug_span!("sync interval thread")),

Review comment (suggestion):
*edit: I forgot that the first tick is skipped.
But I think we prob want to structure it like this so the lock isn't held between ticks:
```rust
                 loop {
                        tokio::select! {
                            _ = &mut cancel_rx => break,
                            _ = interval.tick() => {
                                let mut ctx = sync_ctx.lock().await;
                                let result = if remote_writes {
                                    crate::sync::try_pull(&mut ctx, &conn).await
                                } else {
                                    crate::sync::sync_offline(&mut ctx, &conn).await
                                };
                                if let Err(e) = result {
                                    tracing::error!("Error syncing database: {}", e);
                                }
                          }
                     }
                }
```

Code after:
            if let Some(sync_interval) = sync_interval {
                let (cancel_tx, mut cancel_rx) = tokio::sync::oneshot::channel::<()>();

                let sync_span = tracing::debug_span!("sync_interval");
                let _enter = sync_span.enter();

                let sync_ctx = db.sync_ctx.as_ref().unwrap().clone();
                {
                    let mut ctx = sync_ctx.lock().await;
                    crate::sync::bootstrap_db(&mut ctx).await?;
                    tracing::debug!("finished bootstrap with sync interval");
                }

                // db.connect creates a local db file, so it is important that we always call
                // `bootstrap_db` (for synced dbs) before calling connect. Otherwise, the sync
                // protocol skips calling `export` endpoint causing slowdown in initial bootstrap.
                let conn = db.connect()?;

                tokio::spawn(
                    async move {
                        let mut interval = tokio::time::interval(sync_interval);

                        loop {
                            tokio::select! {
                                _ = &mut cancel_rx => break,
                                _ = interval.tick() => {
                                    tracing::debug!("trying to sync");

                                    let mut ctx = sync_ctx.lock().await;

                                    let result = if remote_writes {
                                        crate::sync::try_pull(&mut ctx, &conn).await
                                    } else {
                                        crate::sync::sync_offline(&mut ctx, &conn).await
                                    };

                                    if let Err(e) = result {
                                        tracing::error!("Error syncing database: {}", e);
                                    }
                                }
                            }
                        }
                    }
                    .instrument(tracing::debug_span!("sync interval thread")),
                );

                bg_abort.replace(std::sync::Arc::new(crate::sync::DropAbort(Some(cancel_tx))));
            }

            Ok(Database {
                db_type: DbType::Offline {