Skip to content

Commit 4230188

Browse files
[Fix] CRUD Upload on Reconnect (#203)
1 parent 45eed64 commit 4230188

File tree

21 files changed

+300
-30
lines changed

21 files changed

+300
-30
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,37 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## 2024-10-31
7+
8+
### Changes
9+
10+
---
11+
12+
Packages with breaking changes:
13+
14+
- There are no breaking changes in this release.
15+
16+
Packages with other changes:
17+
18+
- [`powersync` - `v1.8.9`](#powersync---v189)
19+
- [`powersync_attachments_helper` - `v0.6.13`](#powersync_attachments_helper---v0613)
20+
- [`powersync_flutter_libs` - `v0.4.2`](#powersync_flutter_libs---v042)
21+
22+
---
23+
24+
#### `powersync` - `v1.8.9`
25+
26+
- **FIX**: Issue where CRUD uploads were not triggered when the SDK reconnected to the PowerSync service after being offline.
27+
28+
#### `powersync_attachments_helper` - `v0.6.13`
29+
30+
- Update a dependency to the latest release.
31+
32+
#### `powersync_flutter_libs` - `v0.4.2`
33+
34+
- Update a dependency to the latest release.
35+
36+
637
## 2024-10-21
738

839
### Changes

demos/django-todolist/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ environment:
1010
dependencies:
1111
flutter:
1212
sdk: flutter
13-
powersync: ^1.8.8
13+
powersync: ^1.8.9
1414
path_provider: ^2.1.1
1515
path: ^1.8.3
1616
logging: ^1.2.0

demos/supabase-anonymous-auth/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ dependencies:
1111
flutter:
1212
sdk: flutter
1313

14-
powersync: ^1.8.8
14+
powersync: ^1.8.9
1515
path_provider: ^2.1.1
1616
supabase_flutter: ^2.0.2
1717
path: ^1.8.3

demos/supabase-edge-function-auth/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ dependencies:
1111
flutter:
1212
sdk: flutter
1313

14-
powersync: ^1.8.8
14+
powersync: ^1.8.9
1515
path_provider: ^2.1.1
1616
supabase_flutter: ^2.0.2
1717
path: ^1.8.3

demos/supabase-simple-chat/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies:
3737

3838
supabase_flutter: ^2.0.2
3939
timeago: ^3.6.0
40-
powersync: ^1.8.8
40+
powersync: ^1.8.9
4141
path_provider: ^2.1.1
4242
path: ^1.8.3
4343
logging: ^1.2.0

demos/supabase-todolist-drift/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ environment:
99
dependencies:
1010
flutter:
1111
sdk: flutter
12-
powersync_attachments_helper: ^0.6.12
13-
powersync: ^1.8.8
12+
powersync_attachments_helper: ^0.6.13
13+
powersync: ^1.8.9
1414
path_provider: ^2.1.1
1515
supabase_flutter: ^2.0.1
1616
path: ^1.8.3

demos/supabase-todolist-optional-sync/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ environment:
1010
dependencies:
1111
flutter:
1212
sdk: flutter
13-
powersync: ^1.8.8
13+
powersync: ^1.8.9
1414
path_provider: ^2.1.1
1515
supabase_flutter: ^2.0.1
1616
path: ^1.8.3

demos/supabase-todolist/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ environment:
1010
dependencies:
1111
flutter:
1212
sdk: flutter
13-
powersync_attachments_helper: ^0.6.12
14-
powersync: ^1.8.8
13+
powersync_attachments_helper: ^0.6.13
14+
powersync: ^1.8.9
1515
path_provider: ^2.1.1
1616
supabase_flutter: ^2.0.1
1717
path: ^1.8.3

packages/powersync/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.8.9
2+
3+
- **FIX**: issue where CRUD uploads were not triggered when the SDK reconnected to the PowerSync service after being offline.
4+
15
## 1.8.8
26

37
- Update dependency `powersync_flutter_libs`

packages/powersync/lib/src/streaming_sync.dart

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ class StreamingSyncImplementation {
2727

2828
final Future<void> Function() uploadCrud;
2929

30+
// An internal controller which is used to trigger CRUD uploads internally
31+
// e.g. when reconnecting.
32+
// This is only a broadcast controller since the `crudLoop` method is public
33+
// and could potentially be called multiple times externally.
34+
final StreamController<Null> _internalCrudTriggerController =
35+
StreamController<Null>.broadcast();
36+
3037
final Stream crudUpdateTriggerStream;
3138

3239
final StreamController<SyncStatus> _statusStreamController =
@@ -92,6 +99,9 @@ class StreamingSyncImplementation {
9299
if (_safeToClose) {
93100
_client.close();
94101
}
102+
103+
await _internalCrudTriggerController.close();
104+
95105
// wait for completeAbort() to be called
96106
await future;
97107

@@ -144,7 +154,7 @@ class StreamingSyncImplementation {
144154

145155
// On error, wait a little before retrying
146156
// When aborting, don't wait
147-
await Future.any([Future.delayed(retryDelay), _abort!.onAbort]);
157+
await _delayRetry();
148158
}
149159
}
150160
} finally {
@@ -155,10 +165,14 @@ class StreamingSyncImplementation {
155165
Future<void> crudLoop() async {
156166
await uploadAllCrud();
157167

158-
await for (var _ in crudUpdateTriggerStream) {
159-
if (_abort?.aborted == true) {
160-
break;
161-
}
168+
// Trigger a CRUD upload whenever the upstream trigger fires
169+
// as-well-as whenever the sync stream reconnects.
170+
// This has the potential (in rare cases) to affect the crudThrottleTime,
171+
// but it should not result in excessive uploads since the
172+
// sync reconnects are also throttled.
173+
// The stream here is closed on abort.
174+
await for (var _ in mergeStreams(
175+
[crudUpdateTriggerStream, _internalCrudTriggerController.stream])) {
162176
await uploadAllCrud();
163177
}
164178
}
@@ -170,6 +184,13 @@ class StreamingSyncImplementation {
170184

171185
while (true) {
172186
try {
187+
// It's possible that an abort or disconnect operation could
188+
// be followed by a `close` operation. The close would cause these
189+
// operations, which use the DB, to throw an exception. Breaking the loop
190+
// here prevents unnecessary potential (caught) exceptions.
191+
if (aborted) {
192+
break;
193+
}
173194
// This is the first item in the FIFO CRUD queue.
174195
CrudEntry? nextCrudItem = await adapter.nextCrudItem();
175196
if (nextCrudItem != null) {
@@ -196,7 +217,7 @@ class StreamingSyncImplementation {
196217
checkedCrudItem = null;
197218
isolateLogger.warning('Data upload error', e, stacktrace);
198219
_updateStatus(uploading: false, uploadError: e);
199-
await Future.delayed(retryDelay);
220+
await _delayRetry();
200221
if (!isConnected) {
201222
// Exit the upload loop if the sync stream is no longer connected
202223
break;
@@ -298,6 +319,9 @@ class StreamingSyncImplementation {
298319
Future<void>? credentialsInvalidation;
299320
bool haveInvalidated = false;
300321

322+
// Trigger a CRUD upload on reconnect
323+
_internalCrudTriggerController.add(null);
324+
301325
await for (var line in merged) {
302326
if (aborted) {
303327
break;
@@ -465,6 +489,12 @@ class StreamingSyncImplementation {
465489
yield parseStreamingSyncLine(line as Map<String, dynamic>);
466490
}
467491
}
492+
493+
/// Delays the standard `retryDelay` Duration, but exits early if
494+
/// an abort has been requested.
495+
Future<void> _delayRetry() async {
496+
await Future.any([Future.delayed(retryDelay), _abort!.onAbort]);
497+
}
468498
}
469499

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

0 commit comments

Comments
 (0)