@@ -2,66 +2,74 @@ use pg_schema_cache::SchemaCache;
22use sqlx:: { postgres:: PgListener , PgPool } ;
33use tokio:: task:: JoinHandle ;
44
5- #[ derive( Debug ) ]
65pub ( crate ) struct DbConnection {
76 pool : PgPool ,
87 connection_string : String ,
9- schema_update_handle : Option < JoinHandle < ( ) > > ,
8+ schema_update_handle : JoinHandle < ( ) > ,
9+ close_tx : tokio:: sync:: oneshot:: Sender < ( ) > ,
1010}
1111
1212impl DbConnection {
13- pub ( crate ) async fn new ( connection_string : String ) -> Result < Self , sqlx:: Error > {
14- let pool = PgPool :: connect ( & connection_string) . await ?;
15- Ok ( Self {
16- pool,
17- connection_string : connection_string,
18- schema_update_handle : None ,
19- } )
20- }
21-
22- pub ( crate ) fn connected_to ( & self , connection_string : & str ) -> bool {
23- connection_string == self . connection_string
24- }
25-
26- pub ( crate ) async fn close ( self ) {
27- if self . schema_update_handle . is_some ( ) {
28- self . schema_update_handle . unwrap ( ) . abort ( ) ;
29- }
30- self . pool . close ( ) . await ;
31- }
32-
33- pub ( crate ) async fn listen_for_schema_updates < F > (
34- & mut self ,
13+ pub ( crate ) async fn new < F > (
14+ connection_string : String ,
3515 on_schema_update : F ,
36- ) -> anyhow :: Result < ( ) >
16+ ) -> Result < Self , sqlx :: Error >
3717 where
3818 F : Fn ( SchemaCache ) -> ( ) + Send + ' static ,
3919 {
40- let mut listener = PgListener :: connect_with ( & self . pool ) . await ?;
20+ let pool = PgPool :: connect ( & connection_string) . await ?;
21+
22+ let mut listener = PgListener :: connect_with ( & pool) . await ?;
4123 listener. listen_all ( [ "postgres_lsp" , "pgrst" ] ) . await ?;
4224
43- let pool = self . pool . clone ( ) ;
25+ let ( close_tx, close_rx) = tokio:: sync:: oneshot:: channel :: < ( ) > ( ) ;
26+
27+ let cloned_pool = pool. clone ( ) ;
28+
29+ let schema_update_handle: JoinHandle < ( ) > = tokio:: spawn ( async move {
30+ let mut moved_rx = close_rx;
4431
45- let handle: JoinHandle < ( ) > = tokio:: spawn ( async move {
4632 loop {
47- match listener. recv ( ) . await {
48- Ok ( not) => {
49- if not. payload ( ) . to_string ( ) == "reload schema" {
50- let schema_cache = SchemaCache :: load ( & pool) . await ;
51- on_schema_update ( schema_cache) ;
52- } ;
33+ tokio:: select! {
34+ res = listener. recv( ) => {
35+ match res {
36+ Ok ( not) => {
37+ if not. payload( ) . to_string( ) == "reload schema" {
38+ let schema_cache = SchemaCache :: load( & cloned_pool) . await ;
39+ on_schema_update( schema_cache) ;
40+ } ;
41+ }
42+ Err ( why) => {
43+ eprintln!( "Error receiving notification: {:?}" , why) ;
44+ break ;
45+ }
46+ }
5347 }
54- Err ( why ) => {
55- eprintln ! ( "Error receiving notification: {:?}" , why ) ;
56- break ;
48+
49+ _ = & mut moved_rx => {
50+ return ;
5751 }
5852 }
5953 }
6054 } ) ;
6155
62- self . schema_update_handle = Some ( handle) ;
56+ Ok ( Self {
57+ pool,
58+ connection_string : connection_string,
59+ schema_update_handle,
60+ close_tx,
61+ } )
62+ }
63+
64+ pub ( crate ) fn connected_to ( & self , connection_string : & str ) -> bool {
65+ connection_string == self . connection_string
66+ }
67+
68+ pub ( crate ) async fn close ( self ) {
69+ let _ = self . close_tx . send ( ( ) ) ;
70+ let _ = self . schema_update_handle . await ;
6371
64- Ok ( ( ) )
72+ self . pool . close ( ) . await ;
6573 }
6674
6775 pub ( crate ) fn get_pool ( & self ) -> PgPool {
0 commit comments