Skip to content

Commit 6a4e650

Browse files
exit crud loop on disconnect faster
1 parent b771349 commit 6a4e650

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

packages/powersync/lib/src/streaming_sync.dart

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class StreamingSyncImplementation {
154154

155155
// On error, wait a little before retrying
156156
// When aborting, don't wait
157-
await Future.any([Future.delayed(retryDelay), _abort!.onAbort]);
157+
await _delayRetry();
158158
}
159159
}
160160
} finally {
@@ -173,11 +173,9 @@ class StreamingSyncImplementation {
173173
// This has the potential (in rare cases) to affect the crudThrottleTime,
174174
// but it should not result in excessive uploads since the
175175
// sync reconnects are also throttled.
176+
// The stream here is closed on abort.
176177
await for (var _ in mergeStreams(
177178
[crudUpdateTriggerStream, _internalCrudTriggerController.stream])) {
178-
if (_abort?.aborted == true) {
179-
break;
180-
}
181179
await uploadAllCrud();
182180
}
183181
}
@@ -189,6 +187,13 @@ class StreamingSyncImplementation {
189187

190188
while (true) {
191189
try {
190+
// It's possible that an abort or disconnect operation could
191+
// be followed by a `close` operation. The close would cause these
192+
// operations, which use the DB, to throw an exception. Breaking the loop
193+
// here prevents unnecessary potential (caught) exceptions.
194+
if (aborted) {
195+
break;
196+
}
192197
// This is the first item in the FIFO CRUD queue.
193198
CrudEntry? nextCrudItem = await adapter.nextCrudItem();
194199
if (nextCrudItem != null) {
@@ -215,7 +220,7 @@ class StreamingSyncImplementation {
215220
checkedCrudItem = null;
216221
isolateLogger.warning('Data upload error', e, stacktrace);
217222
_updateStatus(uploading: false, uploadError: e);
218-
await Future.delayed(retryDelay);
223+
await _delayRetry();
219224
if (!isConnected) {
220225
// Exit the upload loop if the sync stream is no longer connected
221226
break;
@@ -487,6 +492,12 @@ class StreamingSyncImplementation {
487492
yield parseStreamingSyncLine(line as Map<String, dynamic>);
488493
}
489494
}
495+
496+
/// Delays the standard `retryDelay` Duration, but exists early if
497+
/// an abort has been requested.
498+
Future<void> _delayRetry() async {
499+
await Future.any([Future.delayed(retryDelay), _abort!.onAbort]);
500+
}
490501
}
491502

492503
/// Attempt to give a basic summary of the error for cases where the full error

packages/powersync/test/upload_test.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ void main() {
6666

6767
powersync =
6868
await testUtils.setupPowerSync(path: path, logger: testWarningLogger);
69-
powersync.retryDelay = Duration(milliseconds: 0);
69+
// Use a short retry delay here.
70+
// A zero retry delay makes this test unstable, since it expects `2` error logs later.
71+
powersync.retryDelay = Duration(milliseconds: 100);
7072
var connector = TestConnector(credentialsCallback, uploadData);
7173
powersync.connect(connector: connector);
7274

0 commit comments

Comments
 (0)