10
10
from jupyter_ydoc .ybasedoc import YBaseDoc
11
11
from pycrdt import Doc
12
12
from pycrdt_websocket .ystore import BaseYStore
13
- from traitlets import Bool , Float , Type
13
+ from traitlets import Bool , Float , Type , Set , Instance
14
14
15
15
from .handlers import DocSessionHandler , YDocWebSocketHandler
16
16
from .loaders import FileLoaderMapping
@@ -75,6 +75,10 @@ class YDocExtension(ExtensionApp):
75
75
model.""" ,
76
76
)
77
77
78
+ _running_ywebsocket_server = Instance (asyncio .Task , allow_none = True )
79
+ ywebsocket_server = Instance (JupyterWebsocketServer , allow_none = True )
80
+
81
+
78
82
def initialize (self ):
79
83
super ().initialize ()
80
84
self .serverapp .event_logger .register_event_schema (EVENTS_SCHEMA_PATH )
@@ -90,6 +94,13 @@ def initialize_settings(self):
90
94
}
91
95
)
92
96
97
+ self .ywebsocket_server = JupyterWebsocketServer (
98
+ rooms_ready = False ,
99
+ auto_clean_rooms = False ,
100
+ ystore_class = self .ystore_class ,
101
+ log = self .log ,
102
+ )
103
+
93
104
def initialize_handlers (self ):
94
105
self .serverapp .web_app .settings .setdefault (
95
106
"page_config_data" ,
@@ -103,13 +114,6 @@ def initialize_handlers(self):
103
114
for k , v in self .config .get (self .ystore_class .__name__ , {}).items ():
104
115
setattr (self .ystore_class , k , v )
105
116
106
- self .ywebsocket_server = JupyterWebsocketServer (
107
- rooms_ready = False ,
108
- auto_clean_rooms = False ,
109
- ystore_class = self .ystore_class ,
110
- log = self .log ,
111
- )
112
-
113
117
# self.settings is local to the ExtensionApp but here we need
114
118
# the global app settings in which the file id manager will register
115
119
# itself maybe at a later time.
@@ -134,6 +138,33 @@ def initialize_handlers(self):
134
138
]
135
139
)
136
140
141
+ async def start_extension (self ):
142
+ """Start the y-websocket server.
143
+ """
144
+ self .log .info ("Starting the Collaborative Document Server." )
145
+
146
+ def _restart_or_teardown_yserver (_ ):
147
+ """If the y websocket server task stopped due to an exception, restart it.
148
+
149
+ If the y-websocket server was cancelled on purpose, tear it down.
150
+ """
151
+ self .ywebsocket_server ._started = None
152
+ self .ywebsocket_server ._starting = False
153
+ self .ywebsocket_server ._task_group = None
154
+ # If an exception was raised, restart the websocket server.
155
+ if self ._running_ywebsocket_server .exception ():
156
+ self .log .error (self ._running_ywebsocket_server .exception ())
157
+ self .log .warning ("Restarting the Collaborative Document Server." )
158
+ self ._running_ywebsocket_server = asyncio .create_task (self .ywebsocket_server .start ())
159
+ self ._running_ywebsocket_server .add_done_callback (_restart_or_teardown_yserver )
160
+ return
161
+ self .log .info ("Stopping the Collaborative Document Server." )
162
+
163
+ # Start the websocket server
164
+ self ._running_ywebsocket_server = asyncio .create_task (self .ywebsocket_server .start ())
165
+ # If the websocket crashes for any reason, let's restart it automatically and log errors.
166
+ self ._running_ywebsocket_server .add_done_callback (_restart_or_teardown_yserver )
167
+
137
168
async def get_document (
138
169
self : YDocExtension ,
139
170
* ,
0 commit comments