1+ use std:: pin:: Pin ;
12use std:: sync:: Arc ;
23use std:: time:: Duration ;
34
5+ use futures:: Future ;
46use futures_core:: future:: BoxFuture ;
57use futures_core:: Stream ;
68use libsql_replication:: rpc:: proxy:: proxy_client:: ProxyClient ;
@@ -9,7 +11,7 @@ use libsql_replication::rpc::proxy::{
911} ;
1012use libsql_sys:: EncryptionConfig ;
1113use parking_lot:: Mutex as PMutex ;
12- use tokio:: sync:: { mpsc, watch , Mutex } ;
14+ use tokio:: sync:: { mpsc, Mutex } ;
1315use tokio_stream:: StreamExt ;
1416use tonic:: transport:: Channel ;
1517use tonic:: { Code , Request , Streaming } ;
@@ -23,16 +25,21 @@ use crate::replication::FrameNo;
2325use crate :: stats:: Stats ;
2426use crate :: { Result , DEFAULT_AUTO_CHECKPOINT } ;
2527
28+ use super :: connection_core:: GetCurrentFrameNo ;
2629use super :: program:: DescribeResponse ;
2730use super :: { Connection , RequestContext } ;
2831use super :: { MakeConnection , Program } ;
2932
3033pub type RpcStream = Streaming < ExecResp > ;
34+ pub type WaitForFrameNo = Arc <
35+ dyn Fn ( FrameNo ) -> Pin < Box < dyn Future < Output = ( ) > + Send + ' static > > + Send + ' static + Sync ,
36+ > ;
3137
3238pub struct MakeWriteProxyConn < M > {
3339 client : ProxyClient < Channel > ,
3440 stats : Arc < Stats > ,
35- applied_frame_no_receiver : watch:: Receiver < Option < FrameNo > > ,
41+ wait_for_frame_no : WaitForFrameNo ,
42+ get_current_frame_no : GetCurrentFrameNo ,
3643 max_response_size : u64 ,
3744 max_total_response_size : u64 ,
3845 primary_replication_index : Option < FrameNo > ,
@@ -47,23 +54,25 @@ impl<M> MakeWriteProxyConn<M> {
4754 channel : Channel ,
4855 uri : tonic:: transport:: Uri ,
4956 stats : Arc < Stats > ,
50- applied_frame_no_receiver : watch :: Receiver < Option < FrameNo > > ,
57+ wait_for_frame_no : WaitForFrameNo ,
5158 max_response_size : u64 ,
5259 max_total_response_size : u64 ,
5360 primary_replication_index : Option < FrameNo > ,
5461 encryption_config : Option < EncryptionConfig > ,
5562 make_read_only_conn : M ,
63+ get_current_frame_no : GetCurrentFrameNo ,
5664 ) -> Self {
5765 let client = ProxyClient :: with_origin ( channel, uri) ;
5866 Self {
5967 client,
6068 stats,
61- applied_frame_no_receiver ,
69+ wait_for_frame_no ,
6270 max_response_size,
6371 max_total_response_size,
6472 make_read_only_conn,
6573 primary_replication_index,
6674 encryption_config,
75+ get_current_frame_no,
6776 }
6877 }
6978}
@@ -78,14 +87,15 @@ where
7887 Ok ( WriteProxyConnection :: new (
7988 self . client . clone ( ) ,
8089 self . stats . clone ( ) ,
81- self . applied_frame_no_receiver . clone ( ) ,
90+ self . wait_for_frame_no . clone ( ) ,
8291 QueryBuilderConfig {
8392 max_size : Some ( self . max_response_size ) ,
8493 max_total_size : Some ( self . max_total_response_size ) ,
8594 auto_checkpoint : DEFAULT_AUTO_CHECKPOINT ,
8695 encryption_config : self . encryption_config . clone ( ) ,
8796 } ,
8897 self . primary_replication_index ,
98+ self . get_current_frame_no . clone ( ) ,
8999 self . make_read_only_conn . create ( ) . await ?,
90100 ) ?)
91101 }
@@ -100,8 +110,9 @@ pub struct WriteProxyConnection<R, C> {
100110 /// any subsequent read on this connection must wait for the replicator to catch up with this
101111 /// frame_no
102112 last_write_frame_no : PMutex < Option < FrameNo > > ,
103- /// Notifier from the repliator of the currently applied frameno
104- applied_frame_no_receiver : watch:: Receiver < Option < FrameNo > > ,
113+ /// Notifier from the replicator of the currently applied frame_no
114+ wait_for_frame_no : WaitForFrameNo ,
115+ get_current_frame_no : GetCurrentFrameNo ,
105116 builder_config : QueryBuilderConfig ,
106117 stats : Arc < Stats > ,
107118
@@ -115,21 +126,23 @@ impl<C: Connection> WriteProxyConnection<RpcStream, C> {
115126 fn new (
116127 write_proxy : ProxyClient < Channel > ,
117128 stats : Arc < Stats > ,
118- applied_frame_no_receiver : watch :: Receiver < Option < FrameNo > > ,
129+ wait_for_frame_no : WaitForFrameNo ,
119130 builder_config : QueryBuilderConfig ,
120131 primary_replication_index : Option < u64 > ,
132+ get_current_frame_no : GetCurrentFrameNo ,
121133 read_conn : C ,
122134 ) -> Result < Self > {
123135 Ok ( Self {
124136 read_conn,
125137 write_proxy,
126138 state : Mutex :: new ( TxnStatus :: Init ) ,
127139 last_write_frame_no : Default :: default ( ) ,
128- applied_frame_no_receiver ,
140+ wait_for_frame_no ,
129141 builder_config,
130142 stats,
131143 remote_conn : Default :: default ( ) ,
132144 primary_replication_index,
145+ get_current_frame_no,
133146 } )
134147 }
135148
@@ -200,15 +213,7 @@ impl<C: Connection> WriteProxyConnection<RpcStream, C> {
200213 let current_fno = replication_index. or_else ( || * self . last_write_frame_no . lock ( ) ) ;
201214 match current_fno {
202215 Some ( current_frame_no) => {
203- let mut receiver = self . applied_frame_no_receiver . clone ( ) ;
204- receiver
205- . wait_for ( |last_applied| match last_applied {
206- Some ( x) => * x >= current_frame_no,
207- None => true ,
208- } )
209- . await
210- . map_err ( |_| Error :: ReplicatorExited ) ?;
211-
216+ ( self . wait_for_frame_no ) ( current_frame_no) . await ;
212217 Ok ( ( ) )
213218 }
214219 None => Ok ( ( ) ) ,
@@ -220,7 +225,7 @@ impl<C: Connection> WriteProxyConnection<RpcStream, C> {
220225 fn should_proxy ( & self ) -> bool {
221226 // There primary has data
222227 if let Some ( primary_index) = self . primary_replication_index {
223- let last_applied = * self . applied_frame_no_receiver . borrow ( ) ;
228+ let last_applied = ( self . get_current_frame_no ) ( ) ;
224229 // if we either don't have data while the primary has, or the data we have is
225230 // anterior to that of the primary when we loaded the namespace, then proxy the
226231 // request to the primary
0 commit comments