@@ -55,6 +55,8 @@ class LanguageServerSessionBase(
55
55
thread = Instance (
56
56
Thread , help = "worker thread for running an event loop" , allow_none = True
57
57
)
58
+ main_loop = Instance (
59
+ IOLoop , help = "the event loop of the main thread" , allow_none = True )
58
60
writer = Instance (LspStreamWriter , help = "the JSON-RPC writer" , allow_none = True )
59
61
reader = Instance (LspStreamReader , help = "the JSON-RPC reader" , allow_none = True )
60
62
from_lsp = Instance (
@@ -107,6 +109,7 @@ def start(self):
107
109
108
110
will return as soon as the session is ready for communication
109
111
"""
112
+ self .main_loop = IOLoop .current ()
110
113
self .started .clear ()
111
114
self .thread = Thread (target = anyio .run , kwargs = {"func" : self .run })
112
115
self .thread .start ()
@@ -121,6 +124,7 @@ def stop(self):
121
124
# wait for the session to get cleaned up
122
125
if self .thread and self .thread .is_alive ():
123
126
self .thread .join ()
127
+ self .main_loop = None
124
128
125
129
async def run (self ):
126
130
"""run this session in a cancel scope and clean everything up on cancellation
@@ -189,7 +193,7 @@ def now(self):
189
193
return datetime .now (timezone .utc )
190
194
191
195
async def start_process (self , argv : List [str ]):
192
- """start the language server subprocess giben in argv"""
196
+ """start the language server subprocess given in argv"""
193
197
self .process = await anyio .open_process (
194
198
argv ,
195
199
stdin = subprocess .PIPE ,
@@ -283,7 +287,8 @@ async def _broadcast_from_lsp(self):
283
287
"""
284
288
async for message in self .from_lsp :
285
289
self .last_server_message_at = self .now ()
286
- await self .parent .on_server_message (message , self )
290
+ # handle message in the main thread's event loop
291
+ self .main_loop .add_callback (self .parent .on_server_message , message , self )
287
292
self .from_lsp .task_done ()
288
293
289
294
0 commit comments