@@ -16,7 +16,6 @@ use sqlsync::local::NoopSignal;
1616use sqlsync:: replication:: ReplicationMsg ;
1717use sqlsync:: replication:: ReplicationProtocol ;
1818use sqlsync:: JournalId ;
19- use sqlsync:: Lsn ;
2019use sqlsync:: MemoryJournalFactory ;
2120use sqlsync:: Reducer ;
2221
@@ -141,6 +140,8 @@ fn handle_client(
141140
142141 let mut num_steps = 0 ;
143142
143+ let mut remaining_direct_mutations = 5 ;
144+
144145 loop {
145146 let msg = receive_msg ( & mut socket_reader) ?;
146147 log:: info!( "server: received {:?}" , msg) ;
@@ -157,6 +158,31 @@ fn handle_client(
157158 log:: info!( "server: stepping doc (steps: {})" , num_steps) ;
158159 unlock ! ( |doc| doc. step( ) ?) ;
159160
161+ // trigger a direct increment on the server side after every message
162+ if remaining_direct_mutations > 0 {
163+ remaining_direct_mutations -= 1 ;
164+ unlock ! ( |doc| {
165+ log:: info!( "server: running a direct mutation on the doc" ) ;
166+ doc. mutate_direct( |tx| {
167+ match tx. execute(
168+ "INSERT INTO counter (id, value) VALUES (1, 0)
169+ ON CONFLICT (id) DO UPDATE SET value = value + 1" ,
170+ [ ] ,
171+ ) {
172+ Ok ( _) => Ok :: <_, anyhow:: Error >( ( ) ) ,
173+ // ignore missing table error
174+ Err ( rusqlite:: Error :: SqliteFailure ( _, Some ( msg) ) )
175+ if msg == "no such table: counter" =>
176+ {
177+ log:: info!( "server: skipping direct mutation" ) ;
178+ Ok ( ( ) )
179+ }
180+ Err ( err) => Err ( err) ?,
181+ }
182+ } ) ?;
183+ } ) ;
184+ }
185+
160186 // sync back to the client if needed
161187 unlock ! ( |doc| {
162188 if let Some ( ( msg, mut reader) ) = protocol. sync( doc) ? {
@@ -219,7 +245,16 @@ fn start_client(
219245 let total_mutations = 10 as usize ;
220246 let mut remaining_mutations = total_mutations;
221247
248+ // the total number of sync attempts we will make
249+ let total_syncs = 100 as usize ;
250+ let mut syncs = 0 ;
251+
222252 loop {
253+ syncs += 1 ;
254+ if syncs > total_syncs {
255+ panic ! ( "client({}): too many syncs" , timeline_id) ;
256+ }
257+
223258 let msg = receive_msg ( & mut socket_reader) ?;
224259 log:: info!( "client({}): received {:?}" , timeline_id, msg) ;
225260
@@ -248,25 +283,31 @@ fn start_client(
248283 }
249284
250285 log:: info!( "client({}): QUERYING STATE" , timeline_id) ;
251- doc. query ( |conn| {
252- conn. query_row ( "select value from counter" , [ ] , |row| {
253- let value: Option < i32 > = row. get ( 0 ) ?;
254- log:: info!(
255- "client({}): counter value: {:?}" ,
256- timeline_id,
257- value
258- ) ;
259- Ok ( ( ) )
260- } ) ?;
261-
262- Ok :: < _ , anyhow:: Error > ( ( ) )
286+ let current_value = doc. query ( |conn| {
287+ let value = conn. query_row (
288+ "select value from counter where id = 0" ,
289+ [ ] ,
290+ |row| {
291+ let value: Option < usize > = row. get ( 0 ) ?;
292+ log:: info!(
293+ "client({}): counter value: {:?}" ,
294+ timeline_id,
295+ value
296+ ) ;
297+ Ok ( value)
298+ } ,
299+ ) ?;
300+
301+ Ok :: < _ , anyhow:: Error > ( value)
263302 } ) ?;
264303
265- if let Some ( lsn) = doc. storage_lsn ( ) {
266- // once the storage has reached (total_mutations+1) * num_clients
267- // then we have reached the end
268- log:: info!( "client({}): storage lsn: {}" , timeline_id, lsn) ;
269- if lsn >= ( ( total_mutations * num_clients) + 1 ) as Lsn {
304+ if let Some ( value) = current_value {
305+ log:: info!(
306+ "client({}): storage lsn: {:?}" ,
307+ timeline_id,
308+ doc. storage_lsn( )
309+ ) ;
310+ if value == ( total_mutations * num_clients) {
270311 break ;
271312 }
272313 }
@@ -279,23 +320,47 @@ fn start_client(
279320
280321 // final query, value should be total_mutations * num_clients
281322 doc. query ( |conn| {
282- conn. query_row_and_then ( "select value from counter" , [ ] , |row| {
283- let value: Option < usize > = row. get ( 0 ) ?;
284- log:: info!(
285- "client({}): FINAL counter value: {:?}" ,
286- timeline_id,
287- value
288- ) ;
289- if value != Some ( total_mutations * num_clients) {
290- return Err ( anyhow:: anyhow!(
323+ conn. query_row_and_then (
324+ "select value from counter where id = 0" ,
325+ [ ] ,
326+ |row| {
327+ let value: Option < usize > = row. get ( 0 ) ?;
328+ log:: info!(
329+ "client({}): FINAL counter value: {:?}" ,
330+ timeline_id,
331+ value
332+ ) ;
333+ if value != Some ( total_mutations * num_clients) {
334+ return Err ( anyhow:: anyhow!(
291335 "client({}): counter value is incorrect: {:?}, expected {}" ,
292336 timeline_id,
293337 value,
294338 total_mutations * num_clients
295339 ) ) ;
296- }
297- Ok ( ( ) )
298- } ) ?;
340+ }
341+ Ok ( ( ) )
342+ } ,
343+ ) ?;
344+ conn. query_row_and_then (
345+ "select value from counter where id = 1" ,
346+ [ ] ,
347+ |row| {
348+ let value: Option < usize > = row. get ( 0 ) ?;
349+ log:: info!(
350+ "client({}): FINAL server counter value: {:?}" ,
351+ timeline_id,
352+ value
353+ ) ;
354+ if value. is_none ( ) || value == Some ( 0 ) {
355+ return Err ( anyhow:: anyhow!(
356+ "client({}): server counter value is incorrect: {:?}, expected non-zero value" ,
357+ timeline_id,
358+ value,
359+ ) ) ;
360+ }
361+ Ok ( ( ) )
362+ } ,
363+ ) ?;
299364 Ok :: < _ , anyhow:: Error > ( ( ) )
300365 } ) ?;
301366
0 commit comments