Skip to content

Commit 6882232

Browse files
authored
Add a mode to the Rust SDK with additional logging to a file (#4566)
# Description of Changes In the Rust client SDK, with this PR, doing `.with_debug_to_file("path.txt")` on the connection builder will result in the SDK logging additional verbose info to `path.txt`. # API and ABI breaking changes Adds a new user-facing-ish API to the Rust client SDK. # Expected complexity level and risk 2? Some possibility of deadlock due to adding a new mutex, but this is explicitly not for production use. # Testing - [x] Ran `chat-console-rs` locally with this enabled and got some debug logs out of it.
1 parent 3c60481 commit 6882232

15 files changed

Lines changed: 219 additions & 47 deletions

File tree

crates/codegen/src/rust.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ impl __sdk::InModule for Reducer {{
13081308
}
13091309

13101310
fn print_db_update_defn(module: &ModuleDef, visibility: CodegenVisibility, out: &mut Indenter) {
1311-
writeln!(out, "#[derive(Default)]");
1311+
writeln!(out, "#[derive(Default, Debug)]");
13121312
writeln!(out, "#[allow(non_snake_case)]");
13131313
writeln!(out, "#[doc(hidden)]");
13141314
out.delimited_block(
@@ -1616,6 +1616,7 @@ fn print_const_db_context_types(out: &mut Indenter) {
16161616
out,
16171617
"
16181618
#[doc(hidden)]
1619+
#[derive(Debug)]
16191620
pub struct RemoteModule;
16201621
16211622
impl __sdk::InModule for RemoteModule {{

crates/codegen/tests/snapshots/codegen__codegen_rust.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ _ => unreachable!(),
12301230
}
12311231
}
12321232

1233-
#[derive(Default)]
1233+
#[derive(Default, Debug)]
12341234
#[allow(non_snake_case)]
12351235
#[doc(hidden)]
12361236
pub struct DbUpdate {
@@ -1346,6 +1346,7 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
13461346

13471347

13481348
#[doc(hidden)]
1349+
#[derive(Debug)]
13491350
pub struct RemoteModule;
13501351

13511352
impl __sdk::InModule for RemoteModule {

sdks/rust/src/client_cache.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
//! This module is internal, and may incompatibly change without warning.
44
55
use crate::callbacks::CallbackId;
6-
use crate::db_connection::{PendingMutation, SharedCell};
6+
use crate::db_connection::{debug_log, PendingMutation, SharedCell};
77
use crate::spacetime_module::{InModule, SpacetimeModule, TableUpdate, WithBsatn};
88
use anymap::{any::Any, Map};
99
use bytes::Bytes;
1010
use core::any::type_name;
1111
use core::hash::Hash;
1212
use futures_channel::mpsc;
1313
use spacetimedb_data_structures::map::{hash_map::Entry, HashCollectionExt, HashMap};
14+
use std::fmt::Debug;
15+
use std::fs::File;
16+
use std::io::Write;
1417
use std::marker::PhantomData;
1518
use std::sync::Arc;
1619

@@ -35,6 +38,9 @@ pub struct TableCache<Row> {
3538
/// Entries are added to this map during [`crate::DbConnectionBuilder::build`],
3639
/// via a `register_table` function autogenerated for each table.
3740
pub(crate) unique_indices: HashMap<&'static str, Box<dyn UniqueIndexDyn<Row = Row>>>,
41+
42+
/// Clone of the [`crate::db_connection::DbContextImpl::extra_logging`].
43+
extra_logging: Option<SharedCell<File>>,
3844
}
3945

4046
/// Stores an entry of the typed row value together with its ref count in the table cache.
@@ -59,11 +65,12 @@ pub(crate) struct RowEntry<Row> {
5965
}
6066

6167
// Can't derive this because the `Row` generic messes us up.
62-
impl<Row> Default for TableCache<Row> {
63-
fn default() -> Self {
68+
impl<Row> TableCache<Row> {
69+
fn new(extra_logging: Option<SharedCell<File>>) -> Self {
6470
Self {
6571
entries: Default::default(),
6672
unique_indices: Default::default(),
73+
extra_logging,
6774
}
6875
}
6976
}
@@ -185,7 +192,13 @@ impl<'r, Row> TableAppliedDiff<'r, Row> {
185192
}
186193
}
187194

188-
impl<Row: Clone + Send + Sync + 'static> TableCache<Row> {
195+
impl<Row> TableCache<Row> {
196+
fn debug_log(&self, body: impl FnOnce(&mut File) -> std::result::Result<(), std::io::Error>) {
197+
debug_log(&self.extra_logging, body);
198+
}
199+
}
200+
201+
impl<Row: Clone + Debug + Send + Sync + 'static> TableCache<Row> {
189202
fn handle_delete<'r>(
190203
&mut self,
191204
inserts: &mut RowEventMap<'_, Row>,
@@ -195,8 +208,16 @@ impl<Row: Clone + Send + Sync + 'static> TableCache<Row> {
195208
// Extract the entry and decrement the `ref_count`.
196209
// Only create a delete event if `ref_count = 0`.
197210
let Entry::Occupied(mut entry) = self.entries.entry(delete.bsatn.clone()) else {
211+
self.debug_log(|file| {
212+
writeln!(file, "`handle_delete` for table with row type {}: a delete update should correspond to an existing row in the table cache, but the row {delete:?} was not present", std::any::type_name::<Row>())?;
213+
writeln!(file, "table contents:")?;
214+
for (bsatn, RowEntry { row, ref_count }) in self.entries.iter() {
215+
writeln!(file, "\t{bsatn:?}\n\t\t{row:?}\n\t\tref_count {ref_count}")?;
216+
}
217+
Ok(())
218+
});
198219
// We're guaranteed to never hit this as long as we apply inserts before deletes.
199-
unreachable!("a delete update should correspond to an existing row in the table cache");
220+
unreachable!("a delete update should correspond to an existing row in the table cache, but the row {delete:?} was not present");
200221
};
201222
let ref_count = &mut entry.get_mut().ref_count;
202223
*ref_count -= 1;
@@ -320,19 +341,21 @@ pub struct ClientCache<M: SpacetimeModule + ?Sized> {
320341
/// The strings are table names, since we may have multiple tables with the same row type.
321342
tables: Map<dyn Any + Send + Sync>,
322343

344+
/// Clone of the [`crate::db_connection::DbContextImpl::extra_logging`].
345+
extra_logging: Option<SharedCell<File>>,
346+
323347
_module: PhantomData<M>,
324348
}
325349

326-
impl<M: SpacetimeModule> Default for ClientCache<M> {
327-
fn default() -> Self {
350+
impl<M: SpacetimeModule> ClientCache<M> {
351+
pub(crate) fn new(extra_logging: Option<SharedCell<File>>) -> Self {
328352
Self {
329353
tables: Map::new(),
354+
extra_logging,
330355
_module: PhantomData,
331356
}
332357
}
333-
}
334358

335-
impl<M: SpacetimeModule> ClientCache<M> {
336359
/// Get a handle on the [`TableCache`] which stores rows of type `Row` for the table `table_name`.
337360
pub(crate) fn get_table<Row: InModule<Module = M> + Send + Sync + 'static>(
338361
&self,
@@ -353,12 +376,12 @@ impl<M: SpacetimeModule> ClientCache<M> {
353376
.entry::<HashMap<&'static str, TableCache<Row>>>()
354377
.or_insert_with(Default::default)
355378
.entry(table_name)
356-
.or_default()
379+
.or_insert_with(|| TableCache::new(self.extra_logging.clone()))
357380
}
358381

359382
/// Apply all the mutations in `diff`
360383
/// to the [`TableCache`] which stores rows of type `Row` for the table `table_name`.
361-
pub fn apply_diff_to_table<'r, Row: InModule<Module = M> + Clone + Send + Sync + 'static>(
384+
pub fn apply_diff_to_table<'r, Row: InModule<Module = M> + Clone + Debug + Send + Sync + 'static>(
362385
&mut self,
363386
table_name: &'static str,
364387
diff: &'r TableUpdate<Row>,
@@ -530,7 +553,7 @@ pub struct UniqueConstraintHandle<Row: InModule, Col> {
530553
}
531554

532555
impl<
533-
Row: Clone + InModule + Send + Sync + 'static,
556+
Row: Clone + Debug + InModule + Send + Sync + 'static,
534557
Col: std::any::Any + Eq + std::hash::Hash + Clone + Send + Sync + std::fmt::Debug + 'static,
535558
> UniqueConstraintHandle<Row, Col>
536559
{

0 commit comments

Comments
 (0)