1
- use std:: collections:: HashMap ;
2
1
use std:: collections:: hash_map:: Entry ;
2
+ use std:: collections:: HashMap ;
3
3
use std:: path:: PathBuf ;
4
4
use std:: sync:: Arc ;
5
5
use std:: time:: { Duration , Instant } ;
6
6
7
7
use bytes:: Bytes ;
8
+ use either:: Either ;
8
9
use libsqlx:: libsql:: { LibsqlDatabase , LogCompactor , LogFile , PrimaryType , ReplicaType } ;
9
- use libsqlx:: proxy:: WriteProxyDatabase ;
10
+ use libsqlx:: proxy:: { WriteProxyConnection , WriteProxyDatabase } ;
11
+ use libsqlx:: result_builder:: ResultBuilder ;
10
12
use libsqlx:: {
11
13
Database as _, DescribeResponse , Frame , FrameNo , InjectableDatabase , Injector , LogReadError ,
12
14
ReplicationLogger ,
@@ -27,7 +29,11 @@ use self::config::{AllocConfig, DbConfig};
27
29
28
30
pub mod config;
29
31
30
- type ExecFn = Box < dyn FnOnce ( & mut dyn libsqlx:: Connection ) + Send > ;
32
+ type LibsqlConnection = Either <
33
+ libsqlx:: libsql:: LibsqlConnection < PrimaryType > ,
34
+ WriteProxyConnection < libsqlx:: libsql:: LibsqlConnection < ReplicaType > , DummyConn > ,
35
+ > ;
36
+ type ExecFn = Box < dyn FnOnce ( & mut LibsqlConnection ) + Send > ;
31
37
32
38
#[ derive( Clone ) ]
33
39
pub struct ConnectionId {
@@ -47,10 +53,10 @@ pub struct DummyDb;
47
53
pub struct DummyConn ;
48
54
49
55
impl libsqlx:: Connection for DummyConn {
50
- fn execute_program (
56
+ fn execute_program < B : ResultBuilder > (
51
57
& mut self ,
52
- _pgm : libsqlx:: program:: Program ,
53
- _result_builder : & mut dyn libsqlx :: result_builder :: ResultBuilder ,
58
+ _pgm : & libsqlx:: program:: Program ,
59
+ _result_builder : B ,
54
60
) -> libsqlx:: Result < ( ) > {
55
61
todo ! ( )
56
62
}
@@ -207,7 +213,12 @@ impl FrameStreamer {
207
213
if !self . buffer . is_empty ( ) {
208
214
self . send_frames ( ) . await ;
209
215
}
210
- if self . notifier . wait_for ( |fno| dbg ! ( * fno) >= self . next_frame_no ) . await . is_err ( ) {
216
+ if self
217
+ . notifier
218
+ . wait_for ( |fno| * fno >= self . next_frame_no )
219
+ . await
220
+ . is_err ( )
221
+ {
211
222
break ;
212
223
}
213
224
}
@@ -244,7 +255,9 @@ impl Database {
244
255
path,
245
256
Compactor ,
246
257
false ,
247
- Box :: new ( move |fno| { let _ = sender. send ( fno) ; } ) ,
258
+ Box :: new ( move |fno| {
259
+ let _ = sender. send ( fno) ;
260
+ } ) ,
248
261
)
249
262
. unwrap ( ) ;
250
263
@@ -253,7 +266,7 @@ impl Database {
253
266
replica_streams : HashMap :: new ( ) ,
254
267
frame_notifier : receiver,
255
268
}
256
- } ,
269
+ }
257
270
DbConfig :: Replica { primary_node_id } => {
258
271
let rdb = LibsqlDatabase :: new_replica ( path, MAX_INJECTOR_BUFFER_CAP , ( ) ) . unwrap ( ) ;
259
272
let wdb = DummyDb ;
@@ -285,10 +298,10 @@ impl Database {
285
298
}
286
299
}
287
300
288
- fn connect ( & self ) -> Box < dyn libsqlx :: Connection + Send > {
301
+ fn connect ( & self ) -> LibsqlConnection {
289
302
match self {
290
- Database :: Primary { db, .. } => Box :: new ( db. connect ( ) . unwrap ( ) ) ,
291
- Database :: Replica { db, .. } => Box :: new ( db. connect ( ) . unwrap ( ) ) ,
303
+ Database :: Primary { db, .. } => Either :: Left ( db. connect ( ) . unwrap ( ) ) ,
304
+ Database :: Replica { db, .. } => Either :: Right ( db. connect ( ) . unwrap ( ) ) ,
292
305
}
293
306
}
294
307
}
@@ -315,11 +328,11 @@ pub struct ConnectionHandle {
315
328
impl ConnectionHandle {
316
329
pub async fn exec < F , R > ( & self , f : F ) -> crate :: Result < R >
317
330
where
318
- F : for < ' a > FnOnce ( & ' a mut ( dyn libsqlx :: Connection + ' a ) ) -> R + Send + ' static ,
331
+ F : for < ' a > FnOnce ( & ' a mut LibsqlConnection ) -> R + Send + ' static ,
319
332
R : Send + ' static ,
320
333
{
321
334
let ( sender, ret) = oneshot:: channel ( ) ;
322
- let cb = move |conn : & mut dyn libsqlx :: Connection | {
335
+ let cb = move |conn : & mut LibsqlConnection | {
323
336
let res = f ( conn) ;
324
337
let _ = sender. send ( res) ;
325
338
} ;
@@ -371,9 +384,15 @@ impl Allocation {
371
384
Message :: Handshake { .. } => unreachable ! ( "handshake should have been caught earlier" ) ,
372
385
Message :: ReplicationHandshake { .. } => todo ! ( ) ,
373
386
Message :: ReplicationHandshakeResponse { .. } => todo ! ( ) ,
374
- Message :: Replicate { req_no, next_frame_no } => match & mut self . database {
375
- Database :: Primary { db, replica_streams, frame_notifier } => {
376
- dbg ! ( next_frame_no) ;
387
+ Message :: Replicate {
388
+ req_no,
389
+ next_frame_no,
390
+ } => match & mut self . database {
391
+ Database :: Primary {
392
+ db,
393
+ replica_streams,
394
+ frame_notifier,
395
+ } => {
377
396
let streamer = FrameStreamer {
378
397
logger : db. logger ( ) ,
379
398
database_id : DatabaseId :: from_name ( & self . db_name ) ,
@@ -396,15 +415,15 @@ impl Allocation {
396
415
* old_req_no = req_no;
397
416
old_handle. abort ( ) ;
398
417
}
399
- } ,
418
+ }
400
419
Entry :: Vacant ( e) => {
401
420
let handle = tokio:: spawn ( streamer. run ( ) ) ;
402
421
// For some reason, not yielding causes the task not to be spawned
403
422
tokio:: task:: yield_now ( ) . await ;
404
423
e. insert ( ( req_no, handle) ) ;
405
- } ,
424
+ }
406
425
}
407
- } ,
426
+ }
408
427
Database :: Replica { .. } => todo ! ( "not a primary!" ) ,
409
428
} ,
410
429
Message :: Frames ( frames) => match & mut self . database {
@@ -459,7 +478,7 @@ impl Allocation {
459
478
460
479
struct Connection {
461
480
id : u32 ,
462
- conn : Box < dyn libsqlx :: Connection + Send > ,
481
+ conn : LibsqlConnection ,
463
482
exit : oneshot:: Receiver < ( ) > ,
464
483
exec : mpsc:: Receiver < ExecFn > ,
465
484
}
@@ -470,7 +489,7 @@ impl Connection {
470
489
tokio:: select! {
471
490
_ = & mut self . exit => break ,
472
491
Some ( exec) = self . exec. recv( ) => {
473
- tokio:: task:: block_in_place( || exec( & mut * self . conn) ) ;
492
+ tokio:: task:: block_in_place( || exec( & mut self . conn) ) ;
474
493
}
475
494
}
476
495
}
0 commit comments