|
1 | 1 | # Copyright (c) Jupyter Development Team.
|
2 | 2 | # Distributed under the terms of the Modified BSD License.
|
| 3 | +from __future__ import annotations |
| 4 | + |
| 5 | +import asyncio |
3 | 6 |
|
4 | 7 | from jupyter_server.extension.application import ExtensionApp
|
5 |
| -from traitlets import Float, Int, Type |
| 8 | +from traitlets import Float, Type |
6 | 9 | from ypy_websocket.ystore import BaseYStore
|
7 | 10 |
|
8 | 11 | from .handlers import DocSessionHandler, YDocWebSocketHandler
|
| 12 | +from .loaders import FileLoaderMapping |
9 | 13 | from .stores import SQLiteYStore
|
10 | 14 | from .utils import EVENTS_SCHEMA_PATH
|
| 15 | +from .websocketserver import JupyterWebsocketServer |
11 | 16 |
|
12 | 17 |
|
13 | 18 | class YDocExtension(ExtensionApp):
|
14 | 19 | name = "jupyter_collaboration"
|
15 | 20 |
|
16 |
| - file_poll_interval = Int( |
| 21 | + file_poll_interval = Float( |
17 | 22 | 1,
|
18 | 23 | config=True,
|
19 | 24 | help="""The period in seconds to check for file changes on disk.
|
20 | 25 | Defaults to 1s, if 0 then file changes will only be checked when
|
21 | 26 | saving changes from the front-end.""",
|
22 | 27 | )
|
23 | 28 |
|
24 |
| - document_cleanup_delay = Int( |
| 29 | + document_cleanup_delay = Float( |
25 | 30 | 60,
|
26 | 31 | allow_none=True,
|
27 | 32 | config=True,
|
@@ -61,12 +66,47 @@ def initialize_settings(self):
|
61 | 66 | )
|
62 | 67 |
|
63 | 68 | def initialize_handlers(self):
|
| 69 | + # Set configurable parameters to YStore class |
| 70 | + for k, v in self.config.get(self.ystore_class.__name__, {}).items(): |
| 71 | + setattr(self.ystore_class, k, v) |
| 72 | + |
| 73 | + self.ywebsocket_server = JupyterWebsocketServer( |
| 74 | + rooms_ready=False, |
| 75 | + auto_clean_rooms=False, |
| 76 | + ystore_class=self.ystore_class, |
| 77 | + log=self.log, |
| 78 | + ) |
| 79 | + |
| 80 | + # self.settings is local to the ExtensionApp but here we need |
| 81 | + # the global app settings in which the file id manager will register |
| 82 | + # itself maybe at a later time. |
| 83 | + self.file_loaders = FileLoaderMapping( |
| 84 | + self.serverapp.web_app.settings, self.log, self.file_poll_interval |
| 85 | + ) |
| 86 | + |
64 | 87 | self.handlers.extend(
|
65 | 88 | [
|
66 |
| - (r"/api/collaboration/room/(.*)", YDocWebSocketHandler), |
| 89 | + ( |
| 90 | + r"/api/collaboration/room/(.*)", |
| 91 | + YDocWebSocketHandler, |
| 92 | + { |
| 93 | + "document_cleanup_delay": self.document_cleanup_delay, |
| 94 | + "document_save_delay": self.document_save_delay, |
| 95 | + "file_loaders": self.file_loaders, |
| 96 | + "ystore_class": self.ystore_class, |
| 97 | + "ywebsocket_server": self.ywebsocket_server, |
| 98 | + }, |
| 99 | + ), |
67 | 100 | (r"/api/collaboration/session/(.*)", DocSessionHandler),
|
68 | 101 | ]
|
69 | 102 | )
|
70 | 103 |
|
71 | 104 | async def stop_extension(self):
|
72 |
| - YDocWebSocketHandler.clean_up() |
| 105 | + # Cancel tasks and clean up |
| 106 | + await asyncio.wait( |
| 107 | + [ |
| 108 | + asyncio.create_task(self.ywebsocket_server.clean()), |
| 109 | + asyncio.create_task(self.file_loaders.clear()), |
| 110 | + ], |
| 111 | + timeout=3, |
| 112 | + ) |
0 commit comments