@@ -45,17 +45,12 @@ def __init__(
45
45
46
46
self ._cleaner : asyncio .Task | None = None
47
47
48
+ # the current `self._maybe_save_document()` task.
49
+ self ._maybe_save_task : asyncio .Task | None = None
50
+
48
51
# the task currently saving to disk via FileLoader, if any.
49
52
self ._save_task : asyncio .Task | None = None
50
53
51
- # flag that indicates whether a previous call to
52
- # `self._maybe_save_document()` is waiting to save.
53
- #
54
- # if `self._maybe_save_document()` is called while this flag is `True`,
55
- # then the call does nothing, as a previous task will save the Ydoc
56
- # within `self._save_delay` seconds.
57
- self ._waiting_to_save = False
58
-
59
54
# flag that indicates whether a previous call to
60
55
# `self._maybe_save_document()` should call itself again after
61
56
# `self._save_task` finishes. this is set to `True` when a document
@@ -219,7 +214,18 @@ def _on_document_change(self, target: str, event: Any) -> None:
219
214
document. This tasks are debounced (60 seconds by default) so we
220
215
need to cancel previous tasks before creating a new one.
221
216
"""
222
- asyncio .create_task (self ._maybe_save_document ())
217
+ if self ._maybe_save_task and not self ._maybe_save_task .done ():
218
+ # only one `self._maybe_save_task` needs to be running.
219
+ #
220
+ # if `self._save_task` is already running, then we need to set the
221
+ # `self._should_resave` flag to `True` to indicate that the
222
+ # `_maybe_save_document()` coroutine needs to be re-scheduled after
223
+ # the current `self._save_task` completes.
224
+ if self ._save_task and not self ._save_task .done ():
225
+ self ._should_resave = True
226
+ return
227
+
228
+ self ._maybe_save_task = asyncio .create_task (self ._maybe_save_document ())
223
229
224
230
async def _maybe_save_document (self ) -> None :
225
231
"""
@@ -234,23 +240,8 @@ async def _maybe_save_document(self) -> None:
234
240
# TODO: fix this; if _save_delay is unset, then this never writes to disk
235
241
return
236
242
237
- if self ._waiting_to_save :
238
- # if a previously spawned `self._maybe_save_document()` task is
239
- # waiting to save, then that task will save the Ydoc within
240
- # `self._save_delay` seconds. therefore we can return early.
241
- return
242
-
243
- if self ._save_task and not self ._save_task .done ():
244
- # if we are currently saving, then set the `_should_resave`
245
- # flag. this indicates to the currently running `self._save_task`
246
- # that it should re-call this method after it completes.
247
- self ._should_resave = True
248
- return
249
-
250
243
# save after `self._save_delay` seconds of inactivity
251
- self ._waiting_to_save = True
252
244
await asyncio .sleep (self ._save_delay )
253
- self ._waiting_to_save = False
254
245
255
246
# all async code (i.e. await statements) must be part of this try/except block
256
247
# because this coroutine is run in a cancellable task and cancellation is handled here
@@ -271,7 +262,7 @@ async def _maybe_save_document(self) -> None:
271
262
272
263
if self ._should_resave :
273
264
self ._should_resave = False
274
- asyncio .create_task (self ._maybe_save_document ())
265
+ self . _maybe_save_task = asyncio .create_task (self ._maybe_save_document ())
275
266
276
267
except asyncio .CancelledError :
277
268
return
0 commit comments