Skip to content

Commit 25d158b

Browse files
committed
Merge branch 'gh-851-lazy-initialization' into gh-880-mk2-use-server-http-settings
2 parents bd233fc + a957e61 commit 25d158b

File tree

5 files changed

+55
-31
lines changed

5 files changed

+55
-31
lines changed

python_packages/jupyter_lsp/jupyter_lsp/handlers.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class LanguageServerWebSocketHandler( # type: ignore
2525

2626
language_server = None # type: Optional[Text]
2727

28-
def open(self, language_server):
28+
async def open(self, language_server):
29+
await self.manager.ready()
2930
self.language_server = language_server
3031
self.manager.subscribe(self)
3132
self.log.debug("[{}] Opened a handler".format(self.language_server))
@@ -51,8 +52,10 @@ class LanguageServersHandler(BaseHandler):
5152
def initialize(self, *args, **kwargs):
5253
super().initialize(*args, **kwargs)
5354

54-
def get(self):
55+
async def get(self):
5556
"""finish with the JSON representations of the sessions"""
57+
await self.manager.ready()
58+
5659
response = {
5760
"version": 2,
5861
"sessions": {

python_packages/jupyter_lsp/jupyter_lsp/manager.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
""" A configurable frontend for stdio-based Language Servers
22
"""
3+
import asyncio
34
import os
45
import sys
56
import traceback
@@ -81,6 +82,10 @@ class LanguageServerManager(LanguageServerManagerAPI):
8182
"""
8283
).tag(config=True)
8384

85+
_ready = Bool(
86+
help="""Whether the manager has been initialized""", default_value=False
87+
)
88+
8489
all_listeners = List_(trait=LoadableCallable).tag(config=True)
8590
server_listeners = List_(trait=LoadableCallable).tag(config=True)
8691
client_listeners = List_(trait=LoadableCallable).tag(config=True)
@@ -118,6 +123,12 @@ def initialize(self, *args, **kwargs):
118123
self.init_language_servers()
119124
self.init_listeners()
120125
self.init_sessions()
126+
self._ready = True
127+
128+
async def ready(self):
129+
while not self._ready: # pragma: no cover
130+
asyncio.sleep(0.1)
131+
return True
121132

122133
def init_language_servers(self) -> None:
123134
"""determine the final language server configuration."""

python_packages/jupyter_lsp/jupyter_lsp/serverextension.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,53 @@
88
from .handlers import add_handlers
99
from .manager import LanguageServerManager
1010
from .paths import normalized_uri
11-
from .virtual_documents_shadow import setup_shadow_filesystem
11+
12+
13+
async def initialize(nbapp, virtual_documents_uri): # pragma: no cover
14+
"""Perform lazy initialization."""
15+
import concurrent.futures
16+
17+
from .virtual_documents_shadow import setup_shadow_filesystem
18+
19+
manager = nbapp.language_server_manager
20+
21+
with concurrent.futures.ThreadPoolExecutor() as pool:
22+
await nbapp.io_loop.run_in_executor(pool, manager.initialize)
23+
24+
setup_shadow_filesystem(virtual_documents_uri=virtual_documents_uri)
25+
26+
nbapp.log.debug(
27+
"[lsp] The following Language Servers will be available: {}".format(
28+
json.dumps(manager.language_servers, indent=2, sort_keys=True)
29+
)
30+
)
1231

1332

1433
def load_jupyter_server_extension(nbapp):
1534
"""create a LanguageServerManager and add handlers"""
1635
nbapp.add_traits(language_server_manager=traitlets.Instance(LanguageServerManager))
1736
manager = nbapp.language_server_manager = LanguageServerManager(parent=nbapp)
18-
manager.initialize()
1937

2038
contents = nbapp.contents_manager
2139
page_config = nbapp.web_app.settings.setdefault("page_config_data", {})
2240

41+
root_uri = ""
42+
virtual_documents_uri = ""
43+
2344
# try to set the rootUri from the contents manager path
2445
if hasattr(contents, "root_dir"):
2546
root_uri = normalized_uri(contents.root_dir)
26-
page_config["rootUri"] = root_uri
2747
nbapp.log.debug("[lsp] rootUri will be %s", root_uri)
28-
2948
virtual_documents_uri = normalized_uri(
3049
Path(contents.root_dir) / manager.virtual_documents_dir
3150
)
32-
page_config["virtualDocumentsUri"] = virtual_documents_uri
3351
nbapp.log.debug("[lsp] virtualDocumentsUri will be %s", virtual_documents_uri)
3452
else: # pragma: no cover
35-
page_config["rootUri"] = ""
36-
page_config["virtualDocumentsUri"] = ""
3753
nbapp.log.warn(
3854
"[lsp] %s did not appear to have a root_dir, could not set rootUri",
3955
contents,
4056
)
57+
page_config.update(rootUri=root_uri, virtualDocumentsUri=virtual_documents_uri)
4158

4259
add_handlers(nbapp)
43-
44-
nbapp.log.debug(
45-
"[lsp] The following Language Servers will be available: {}".format(
46-
json.dumps(manager.language_servers, indent=2, sort_keys=True)
47-
)
48-
)
49-
50-
setup_shadow_filesystem(virtual_documents_uri=virtual_documents_uri)
60+
nbapp.io_loop.call_later(0, initialize, nbapp, virtual_documents_uri)

python_packages/jupyter_lsp/jupyter_lsp/tests/test_listener.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ async def all_listener(
7979
assert len(manager._listeners["client"]) == 2
8080
assert len(manager._listeners["all"]) == 2
8181

82-
ws_handler.open(known_server)
82+
await ws_handler.open(known_server)
8383

8484
await ws_handler.on_message(jsonrpc_init_msg)
8585

python_packages/jupyter_lsp/jupyter_lsp/tests/test_session.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from ..schema import SERVERS_RESPONSE
66

77

8-
def assert_status_set(handler, expected_statuses, language_server=None):
9-
handler.get()
8+
async def assert_status_set(handler, expected_statuses, language_server=None):
9+
await handler.get()
1010
payload = handler._payload
1111

1212
errors = list(SERVERS_RESPONSE.iter_errors(payload))
@@ -28,13 +28,13 @@ async def test_start_known(known_server, handlers, jsonrpc_init_msg):
2828

2929
manager.initialize()
3030

31-
assert_status_set(handler, {"not_started"})
31+
await assert_status_set(handler, {"not_started"})
3232

33-
ws_handler.open(known_server)
33+
await ws_handler.open(known_server)
3434
session = manager.sessions[ws_handler.language_server]
3535
assert session.process is not None
3636

37-
assert_status_set(handler, {"started"}, known_server)
37+
await assert_status_set(handler, {"started"}, known_server)
3838

3939
await ws_handler.on_message(jsonrpc_init_msg)
4040

@@ -50,8 +50,8 @@ async def test_start_known(known_server, handlers, jsonrpc_init_msg):
5050
assert not session.handlers
5151
assert not session.process
5252

53-
assert_status_set(handler, {"stopped"}, known_server)
54-
assert_status_set(handler, {"stopped", "not_started"})
53+
await assert_status_set(handler, {"stopped"}, known_server)
54+
await assert_status_set(handler, {"stopped", "not_started"})
5555

5656

5757
@pytest.mark.asyncio
@@ -61,18 +61,18 @@ async def test_start_unknown(known_unknown_server, handlers, jsonrpc_init_msg):
6161
manager = handler.manager
6262
manager.initialize()
6363

64-
assert_status_set(handler, {"not_started"})
64+
await assert_status_set(handler, {"not_started"})
6565

66-
ws_handler.open(known_unknown_server)
66+
await ws_handler.open(known_unknown_server)
6767

68-
assert_status_set(handler, {"not_started"})
68+
await assert_status_set(handler, {"not_started"})
6969

7070
await ws_handler.on_message(jsonrpc_init_msg)
71-
assert_status_set(handler, {"not_started"})
71+
await assert_status_set(handler, {"not_started"})
7272
ws_handler.on_close()
7373

7474
assert not manager.sessions.get(ws_handler.language_server)
75-
assert_status_set(handler, {"not_started"})
75+
await assert_status_set(handler, {"not_started"})
7676

7777

7878
@pytest.mark.asyncio
@@ -92,7 +92,7 @@ async def test_ping(handlers):
9292

9393
assert ws_handler._ping_sent is False
9494

95-
ws_handler.open(a_server)
95+
await ws_handler.open(a_server)
9696

9797
assert ws_handler.ping_callback is not None and ws_handler.ping_callback.is_running
9898
await asyncio.sleep(ws_handler.ping_interval * 3)

0 commit comments

Comments
 (0)