@@ -242,14 +242,20 @@ fn run() -> Result<(), ClientError> {
242242 raced ( & client, & exclusive, false ) ? == 100 ,
243243 ) ?;
244244
245- step ( "What a reader sees while an append is in flight " ) ;
245+ step ( "What a reader sees before an append commits " ) ;
246246 // Nothing, which is the answer that lets a reader poll `@row_count` without
247247 // a lock: the rows arrive with the upload transaction's commit, all at once.
248248 let inflight = format ! ( "{BASE}/inflight" ) ;
249249 client. create ( "table" , & inflight) ?;
250250 client. write_table_rows ( & inflight, entries ( 0 ..10 ) ) ?;
251251 let body = encoded ( entries ( 10 ..40 ) ) ;
252- let ( path, writing) = ( inflight. clone ( ) , client. clone ( ) ) ;
252+ // This outer transaction is the cluster-held boundary for the samples.
253+ // The writer may finish while its thread is winding down, but the rows
254+ // cannot become visible until `commit` below. `is_finished` therefore only
255+ // decides when there are no more useful samples to take; it cannot let the
256+ // final one race the commit.
257+ let tx = client. start_transaction ( ) ?;
258+ let ( path, writing) = ( inflight. clone ( ) , tx. client ( ) . clone ( ) ) ;
253259 let upload = std:: thread:: spawn ( move || {
254260 writing. write_table_streaming ( TablePath :: new ( & path) . append ( ) , Trickle :: new ( body) )
255261 } ) ;
@@ -260,12 +266,10 @@ fn run() -> Result<(), ClientError> {
260266 }
261267 upload. join ( ) . expect ( "the upload thread finished" ) ?;
262268 check (
263- & format ! (
264- "{} readings during the upload, every one of them 10" ,
265- seen. len( )
266- ) ,
269+ & readings_report ( & seen) ,
267270 !seen. is_empty ( ) && seen. iter ( ) . all ( |& n| n == 10 ) ,
268271 ) ?;
272+ tx. commit ( ) ?;
269273 check ( "and 40 once it commits" , client. row_count ( & inflight) ? == 40 ) ?;
270274
271275 benchmark ( & client) ?;
@@ -447,6 +451,11 @@ fn first_line(message: &str) -> &str {
447451 message. lines ( ) . next ( ) . unwrap_or ( message)
448452}
449453
454+ /// What the in-flight check actually observed, including the values on failure.
455+ fn readings_report ( readings : & [ i64 ] ) -> String {
456+ format ! ( "readings before the transaction commits: {readings:?}" )
457+ }
458+
450459fn step ( what : & str ) {
451460 println ! ( "\n == {what}" ) ;
452461}
@@ -463,3 +472,16 @@ fn check(what: &str, passed: bool) -> Result<(), ClientError> {
463472 eprintln ! ( " FAIL {what}" ) ;
464473 Err ( ClientError :: Config ( format ! ( "check failed: {what}" ) ) )
465474}
475+
476+ #[ cfg( test) ]
477+ mod tests {
478+ use super :: readings_report;
479+
480+ #[ test]
481+ fn readings_report_keeps_every_observation ( ) {
482+ assert_eq ! (
483+ readings_report( & [ 10 , 10 , 40 ] ) ,
484+ "readings before the transaction commits: [10, 10, 40]"
485+ ) ;
486+ }
487+ }
0 commit comments