@@ -27,11 +27,11 @@ use pg_hover::HoverParams;
27
27
use pg_schema_cache:: SchemaCache ;
28
28
use pg_workspace:: Workspace ;
29
29
use serde:: { de:: DeserializeOwned , Serialize } ;
30
- use std:: { collections:: HashSet , sync:: Arc , time:: Duration } ;
30
+ use std:: { collections:: HashSet , future :: Future , sync:: Arc , time:: Duration } ;
31
31
use text_size:: TextSize ;
32
- use threadpool:: ThreadPool ;
33
32
34
- use tokio:: sync:: { mpsc, oneshot} ;
33
+ use tokio:: sync:: mpsc;
34
+ use tokio_util:: sync:: CancellationToken ;
35
35
36
36
use crate :: {
37
37
client:: { client_flags:: ClientFlags , LspClient } ,
@@ -72,9 +72,9 @@ impl DbConnection {
72
72
/// For now, we move it into a separate task and use tokio's channels to communicate.
73
73
fn get_client_receiver (
74
74
connection : Connection ,
75
- ) -> ( mpsc:: UnboundedReceiver < Message > , oneshot:: Receiver < ( ) > ) {
75
+ cancel_token : Arc < CancellationToken > ,
76
+ ) -> mpsc:: UnboundedReceiver < Message > {
76
77
let ( message_tx, message_rx) = mpsc:: unbounded_channel ( ) ;
77
- let ( close_tx, close_rx) = oneshot:: channel ( ) ;
78
78
79
79
tokio:: task:: spawn ( async move {
80
80
// TODO: improve Result handling
@@ -83,7 +83,7 @@ fn get_client_receiver(
83
83
84
84
match msg {
85
85
Message :: Request ( r) if connection. handle_shutdown ( & r) . unwrap ( ) => {
86
- close_tx . send ( ( ) ) . unwrap ( ) ;
86
+ cancel_token . cancel ( ) ;
87
87
return ;
88
88
}
89
89
@@ -92,16 +92,15 @@ fn get_client_receiver(
92
92
}
93
93
} ) ;
94
94
95
- ( message_rx, close_rx )
95
+ message_rx
96
96
}
97
97
98
98
pub struct Server {
99
99
client_rx : mpsc:: UnboundedReceiver < Message > ,
100
- close_rx : oneshot :: Receiver < ( ) > ,
100
+ cancel_token : Arc < tokio_util :: sync :: CancellationToken > ,
101
101
client : LspClient ,
102
102
internal_tx : mpsc:: UnboundedSender < InternalMessage > ,
103
103
internal_rx : mpsc:: UnboundedReceiver < InternalMessage > ,
104
- pool : Arc < ThreadPool > ,
105
104
client_flags : Arc < ClientFlags > ,
106
105
ide : Arc < Workspace > ,
107
106
db_conn : Option < DbConnection > ,
@@ -138,10 +137,12 @@ impl Server {
138
137
let cloned_pool = pool. clone ( ) ;
139
138
let cloned_client = client. clone ( ) ;
140
139
141
- let ( client_rx, close_rx) = get_client_receiver ( connection) ;
140
+ let cancel_token = Arc :: new ( CancellationToken :: new ( ) ) ;
141
+
142
+ let client_rx = get_client_receiver ( connection, cancel_token. clone ( ) ) ;
142
143
143
144
let server = Self {
144
- close_rx ,
145
+ cancel_token ,
145
146
client_rx,
146
147
internal_rx,
147
148
internal_tx,
@@ -186,7 +187,6 @@ impl Server {
186
187
} ) ;
187
188
} ,
188
189
) ,
189
- pool,
190
190
} ;
191
191
192
192
Ok ( server)
@@ -200,7 +200,7 @@ impl Server {
200
200
201
201
self . compute_debouncer . clear ( ) ;
202
202
203
- tokio :: spawn ( async move {
203
+ self . spawn_with_cancel ( async move {
204
204
client
205
205
. send_notification :: < ShowMessage > ( ShowMessageParams {
206
206
typ : lsp_types:: MessageType :: INFO ,
@@ -714,15 +714,17 @@ impl Server {
714
714
Q : FnOnce ( ) -> anyhow:: Result < R > + Send + ' static ,
715
715
{
716
716
let client = self . client . clone ( ) ;
717
- self . pool . execute ( move || match query ( ) {
718
- Ok ( result) => {
719
- let response = lsp_server:: Response :: new_ok ( id, result) ;
720
- client. send_response ( response) . unwrap ( ) ;
721
- }
722
- Err ( why) => {
723
- client
724
- . send_error ( id, ErrorCode :: InternalError , why. to_string ( ) )
725
- . unwrap ( ) ;
717
+ self . spawn_with_cancel ( async move {
718
+ match query ( ) {
719
+ Ok ( result) => {
720
+ let response = lsp_server:: Response :: new_ok ( id, result) ;
721
+ client. send_response ( response) . unwrap ( ) ;
722
+ }
723
+ Err ( why) => {
724
+ client
725
+ . send_error ( id, ErrorCode :: InternalError , why. to_string ( ) )
726
+ . unwrap ( ) ;
727
+ }
726
728
}
727
729
} ) ;
728
730
}
@@ -748,9 +750,11 @@ impl Server {
748
750
let client = self . client . clone ( ) ;
749
751
let ide = Arc :: clone ( & self . ide ) ;
750
752
751
- self . pool . execute ( move || {
753
+ self . spawn_with_cancel ( async move {
752
754
let response = lsp_server:: Response :: new_ok ( id, query ( & ide) ) ;
753
- client. send_response ( response) . unwrap ( ) ;
755
+ client
756
+ . send_response ( response)
757
+ . expect ( "Failed to send query to client" ) ;
754
758
} ) ;
755
759
}
756
760
@@ -791,22 +795,21 @@ impl Server {
791
795
async fn process_messages ( & mut self ) -> anyhow:: Result < ( ) > {
792
796
loop {
793
797
tokio:: select! {
794
- _ = & mut self . close_rx => {
798
+ _ = self . cancel_token. cancelled( ) => {
799
+ // Close the loop, proceed to shutdown.
795
800
return Ok ( ( ) )
796
801
} ,
797
802
798
803
msg = self . internal_rx. recv( ) => {
799
804
match msg {
800
- // TODO: handle internal sender close? Is that valid state?
801
- None => return Ok ( ( ) ) ,
802
- Some ( m) => self . handle_internal_message( m)
805
+ None => panic!( "The LSP's internal sender closed. This should never happen." ) ,
806
+ Some ( m) => self . handle_internal_message( m) . await
803
807
}
804
808
} ,
805
809
806
810
msg = self . client_rx. recv( ) => {
807
811
match msg {
808
- // the client sender is closed, we can return
809
- None => return Ok ( ( ) ) ,
812
+ None => panic!( "The LSP's client closed, but not via an 'exit' method. This should never happen." ) ,
810
813
Some ( m) => self . handle_message( m)
811
814
}
812
815
} ,
@@ -848,14 +851,14 @@ impl Server {
848
851
Ok ( ( ) )
849
852
}
850
853
851
- fn handle_internal_message ( & mut self , msg : InternalMessage ) -> anyhow:: Result < ( ) > {
854
+ async fn handle_internal_message ( & mut self , msg : InternalMessage ) -> anyhow:: Result < ( ) > {
852
855
match msg {
853
856
InternalMessage :: SetSchemaCache ( c) => {
854
857
self . ide . set_schema_cache ( c) ;
855
858
self . compute_now ( ) ;
856
859
}
857
860
InternalMessage :: RefreshSchemaCache => {
858
- self . refresh_schema_cache ( ) ;
861
+ self . refresh_schema_cache ( ) . await ;
859
862
}
860
863
InternalMessage :: PublishDiagnostics ( uri) => {
861
864
self . publish_diagnostics ( uri) ?;
@@ -869,10 +872,6 @@ impl Server {
869
872
}
870
873
871
874
fn pull_options ( & mut self ) {
872
- if !self . client_flags . has_configuration {
873
- return ;
874
- }
875
-
876
875
let params = ConfigurationParams {
877
876
items : vec ! [ ConfigurationItem {
878
877
section: Some ( "postgres_lsp" . to_string( ) ) ,
@@ -881,53 +880,72 @@ impl Server {
881
880
} ;
882
881
883
882
let client = self . client . clone ( ) ;
884
- let sender = self . internal_tx . clone ( ) ;
885
- self . pool . execute ( move || {
883
+ let internal_tx = self . internal_tx . clone ( ) ;
884
+ self . spawn_with_cancel ( async move {
886
885
match client. send_request :: < WorkspaceConfiguration > ( params) {
887
886
Ok ( mut json) => {
888
887
let options = client
889
888
. parse_options ( json. pop ( ) . expect ( "invalid configuration request" ) )
890
889
. unwrap ( ) ;
891
890
892
- sender. send ( InternalMessage :: SetOptions ( options) ) . unwrap ( ) ;
891
+ if let Err ( why) = internal_tx. send ( InternalMessage :: SetOptions ( options) ) {
892
+ println ! ( "Failed to set internal options: {}" , why) ;
893
+ }
893
894
}
894
- Err ( _why ) => {
895
- // log::error !("Retrieving configuration failed: {}", why);
895
+ Err ( why ) => {
896
+ println ! ( "Retrieving configuration failed: {}" , why) ;
896
897
}
897
898
} ;
898
899
} ) ;
899
900
}
900
901
901
902
fn register_configuration ( & mut self ) {
902
- if self . client_flags . will_push_configuration {
903
- let registration = Registration {
904
- id : "pull-config" . to_string ( ) ,
905
- method : DidChangeConfiguration :: METHOD . to_string ( ) ,
906
- register_options : None ,
907
- } ;
903
+ let registration = Registration {
904
+ id : "pull-config" . to_string ( ) ,
905
+ method : DidChangeConfiguration :: METHOD . to_string ( ) ,
906
+ register_options : None ,
907
+ } ;
908
908
909
- let params = RegistrationParams {
910
- registrations : vec ! [ registration] ,
911
- } ;
909
+ let params = RegistrationParams {
910
+ registrations : vec ! [ registration] ,
911
+ } ;
912
912
913
- let client = self . client . clone ( ) ;
914
- self . pool . execute ( move || {
915
- if let Err ( _why) = client. send_request :: < RegisterCapability > ( params) {
916
- // log::error!(
917
- // "Failed to register \"{}\" notification: {}",
918
- // DidChangeConfiguration::METHOD,
919
- // why
920
- // );
921
- }
922
- } ) ;
923
- }
913
+ let client = self . client . clone ( ) ;
914
+ self . spawn_with_cancel ( async move {
915
+ if let Err ( why) = client. send_request :: < RegisterCapability > ( params) {
916
+ println ! (
917
+ "Failed to register \" {}\" notification: {}" ,
918
+ DidChangeConfiguration :: METHOD ,
919
+ why
920
+ ) ;
921
+ }
922
+ } ) ;
923
+ }
924
+
925
+ fn spawn_with_cancel < F > ( & self , f : F ) -> tokio:: task:: JoinHandle < ( ) >
926
+ where
927
+ F : Future + Send + ' static ,
928
+ {
929
+ let cancel_token = self . cancel_token . clone ( ) ;
930
+ tokio:: spawn ( async move {
931
+ tokio:: select! {
932
+ _ = cancel_token. cancelled( ) => { } ,
933
+ _ = f => { }
934
+ } ;
935
+ } )
924
936
}
925
937
926
938
pub async fn run ( mut self ) -> anyhow:: Result < ( ) > {
927
- self . register_configuration ( ) ;
928
- self . pull_options ( ) ;
939
+ if self . client_flags . will_push_configuration {
940
+ self . register_configuration ( ) ;
941
+ }
942
+
943
+ if self . client_flags . has_configuration {
944
+ self . pull_options ( ) ;
945
+ }
946
+
929
947
self . process_messages ( ) . await ?;
930
- self . pool . join ( ) ;
948
+
931
949
Ok ( ( ) )
932
950
}
933
951
}
0 commit comments