Skip to content

Commit 50fbb95

Browse files
committed
More worker debugging
1 parent cdee0ef commit 50fbb95

File tree

7 files changed

+62
-36
lines changed

7 files changed

+62
-36
lines changed

demos/benchmarks/pubspec.lock

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ packages:
111111
dependency: "direct main"
112112
description:
113113
name: http
114-
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
114+
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
115115
url: "https://pub.dev"
116116
source: hosted
117-
version: "1.4.0"
117+
version: "1.5.0"
118118
http_parser:
119119
dependency: transitive
120120
description:
@@ -135,26 +135,26 @@ packages:
135135
dependency: transitive
136136
description:
137137
name: leak_tracker
138-
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
138+
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
139139
url: "https://pub.dev"
140140
source: hosted
141-
version: "10.0.9"
141+
version: "11.0.1"
142142
leak_tracker_flutter_testing:
143143
dependency: transitive
144144
description:
145145
name: leak_tracker_flutter_testing
146-
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
146+
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
147147
url: "https://pub.dev"
148148
source: hosted
149-
version: "3.0.9"
149+
version: "3.0.10"
150150
leak_tracker_testing:
151151
dependency: transitive
152152
description:
153153
name: leak_tracker_testing
154-
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
154+
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
155155
url: "https://pub.dev"
156156
source: hosted
157-
version: "3.0.1"
157+
version: "3.0.2"
158158
lints:
159159
dependency: transitive
160160
description:
@@ -281,21 +281,21 @@ packages:
281281
path: "../../packages/powersync"
282282
relative: true
283283
source: path
284-
version: "1.15.0"
284+
version: "1.15.2"
285285
powersync_core:
286286
dependency: "direct overridden"
287287
description:
288288
path: "../../packages/powersync_core"
289289
relative: true
290290
source: path
291-
version: "1.5.0"
291+
version: "1.5.2"
292292
powersync_flutter_libs:
293293
dependency: "direct overridden"
294294
description:
295295
path: "../../packages/powersync_flutter_libs"
296296
relative: true
297297
source: path
298-
version: "0.4.10"
298+
version: "0.4.11"
299299
pub_semver:
300300
dependency: transitive
301301
description:
@@ -337,10 +337,10 @@ packages:
337337
dependency: transitive
338338
description:
339339
name: sqlite3
340-
sha256: "310af39c40dd0bb2058538333c9d9840a2725ae0b9f77e4fd09ad6696aa8f66e"
340+
sha256: f393d92c71bdcc118d6203d07c991b9be0f84b1a6f89dd4f7eed348131329924
341341
url: "https://pub.dev"
342342
source: hosted
343-
version: "2.7.5"
343+
version: "2.9.0"
344344
sqlite3_flutter_libs:
345345
dependency: transitive
346346
description:
@@ -353,18 +353,18 @@ packages:
353353
dependency: transitive
354354
description:
355355
name: sqlite3_web
356-
sha256: "967e076442f7e1233bd7241ca61f3efe4c7fc168dac0f38411bdb3bdf471eb3c"
356+
sha256: "0f6ebcb4992d1892ac5c8b5ecd22a458ab9c5eb6428b11ae5ecb5d63545844da"
357357
url: "https://pub.dev"
358358
source: hosted
359-
version: "0.3.1"
359+
version: "0.3.2"
360360
sqlite_async:
361361
dependency: "direct main"
362362
description:
363363
name: sqlite_async
364-
sha256: a60e8d5c8df8e694933bd5a312c38393e79ad77d784bb91c6f38ba627bfb7aec
364+
sha256: "6116bfc6aef6ce77730b478385ba4a58873df45721f6a9bc6ffabf39b6576e36"
365365
url: "https://pub.dev"
366366
source: hosted
367-
version: "0.11.4"
367+
version: "0.12.1"
368368
stack_trace:
369369
dependency: transitive
370370
description:
@@ -401,10 +401,10 @@ packages:
401401
dependency: transitive
402402
description:
403403
name: test_api
404-
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
404+
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
405405
url: "https://pub.dev"
406406
source: hosted
407-
version: "0.7.4"
407+
version: "0.7.6"
408408
typed_data:
409409
dependency: transitive
410410
description:
@@ -433,10 +433,10 @@ packages:
433433
dependency: transitive
434434
description:
435435
name: vector_math
436-
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
436+
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
437437
url: "https://pub.dev"
438438
source: hosted
439-
version: "2.1.4"
439+
version: "2.2.0"
440440
vm_service:
441441
dependency: transitive
442442
description:
@@ -470,5 +470,5 @@ packages:
470470
source: hosted
471471
version: "3.1.3"
472472
sdks:
473-
dart: ">=3.7.0 <4.0.0"
473+
dart: ">=3.8.0-0 <4.0.0"
474474
flutter: ">=3.27.0"

demos/supabase-todolist/lib/app_config_template.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ class AppConfig {
88
''; // Optional. Only required when syncing attachments and using Supabase Storage. See packages/powersync_attachments_helper.
99
// Whether the PowerSync instance uses sync streams to make fetching todo
1010
// items optional.
11-
static const bool hasSyncStreams = true;
11+
static const bool hasSyncStreams = false;
1212
}

demos/supabase-todolist/lib/widgets/todo_list_page.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class _SyncStreamTodosState extends State<_SyncStreamTodoListWidget> {
132132
false;
133133

134134
if (!hasSynced) {
135-
return const CircularProgressIndicator();
135+
return const Center(child: CircularProgressIndicator());
136136
} else {
137137
return StreamBuilder(
138138
stream: widget.list.watchItems(),

packages/powersync_core/lib/src/sync/connection_manager.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ final class ConnectionManager {
255255
},
256256
});
257257

258-
await _activeGroup.syncMutex.lock(() async {
258+
await _activeGroup.syncConnectMutex.lock(() async {
259259
if (_abortActiveSync == null) {
260260
// Since we're not connected, update the offline sync status to reflect
261261
// the new subscription.

packages/powersync_core/lib/src/sync/instruction.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ sealed class Instruction {
1414
EstablishSyncStream.fromJson(establish as Map<String, Object?>),
1515
{'FetchCredentials': final creds} =>
1616
FetchCredentials.fromJson(creds as Map<String, Object?>),
17-
{'CloseSyncStream': _} => const CloseSyncStream(),
17+
{'CloseSyncStream': final closeOptions as Map<String, Object?>} =>
18+
CloseSyncStream(closeOptions['hide_disconnect'] as bool),
1819
{'FlushFileSystem': _} => const FlushFileSystem(),
1920
{'DidCompleteSync': _} => const DidCompleteSync(),
2021
_ => UnknownSyncInstruction(json)
@@ -142,7 +143,9 @@ final class FetchCredentials implements Instruction {
142143
}
143144

144145
final class CloseSyncStream implements Instruction {
145-
const CloseSyncStream();
146+
final bool hideDisconnect;
147+
148+
const CloseSyncStream(this.hideDisconnect);
146149
}
147150

148151
final class FlushFileSystem implements Instruction {

packages/powersync_core/lib/src/sync/streaming_sync.dart

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,12 @@ class StreamingSyncImplementation implements StreamingSync {
309309
}
310310

311311
Future<void> _rustStreamingSyncIteration() async {
312-
await _ActiveRustStreamingIteration(this).syncIteration();
312+
logger.info('Starting Rust sync iteration');
313+
final response = await _ActiveRustStreamingIteration(this).syncIteration();
314+
logger.info(
315+
'Ending Rust sync iteration. Immediate restart: ${response.immediateRestart}');
316+
// Note: With the current loop in streamingSync(), any return value that
317+
// isn't an exception triggers an immediate restart.
313318
}
314319

315320
Future<(List<BucketRequest>, Map<String, BucketDescription?>)>
@@ -610,7 +615,7 @@ final class _ActiveRustStreamingIteration {
610615
var _hadSyncLine = false;
611616

612617
StreamSubscription<void>? _completedUploads;
613-
final Completer<void> _completedStream = Completer();
618+
final Completer<RustSyncIterationResult> _completedStream = Completer();
614619

615620
_ActiveRustStreamingIteration(this.sync);
616621

@@ -620,7 +625,7 @@ final class _ActiveRustStreamingIteration {
620625
.toList();
621626
}
622627

623-
Future<void> syncIteration() async {
628+
Future<RustSyncIterationResult> syncIteration() async {
624629
try {
625630
await _control(
626631
'start',
@@ -632,7 +637,7 @@ final class _ActiveRustStreamingIteration {
632637
}),
633638
);
634639
assert(_completedStream.isCompleted, 'Should have started streaming');
635-
await _completedStream.future;
640+
return await _completedStream.future;
636641
} finally {
637642
_isActive = false;
638643
_completedUploads?.cancel();
@@ -655,10 +660,12 @@ final class _ActiveRustStreamingIteration {
655660
}).map(ReceivedLine.new);
656661
}
657662

658-
Future<void> _handleLines(EstablishSyncStream request) async {
663+
Future<RustSyncIterationResult> _handleLines(
664+
EstablishSyncStream request) async {
659665
final events = addBroadcast(
660666
_receiveLines(request.request), sync._nonLineSyncEvents.stream);
661667

668+
var needsImmediateRestart = false;
662669
loop:
663670
await for (final event in events) {
664671
if (!_isActive || sync.aborted) {
@@ -674,7 +681,8 @@ final class _ActiveRustStreamingIteration {
674681
await _control('line_text', line);
675682
case UploadCompleted():
676683
await _control('completed_upload');
677-
case AbortCurrentIteration():
684+
case AbortCurrentIteration(:final hideDisconnectState):
685+
needsImmediateRestart = hideDisconnectState;
678686
break loop;
679687
case TokenRefreshComplete():
680688
await _control('refreshed_token');
@@ -683,6 +691,8 @@ final class _ActiveRustStreamingIteration {
683691
convert.json.encode(_encodeSubscriptions(currentSubscriptions)));
684692
}
685693
}
694+
695+
return (immediateRestart: needsImmediateRestart);
686696
}
687697

688698
/// Triggers a local CRUD upload when the first sync line has been received.
@@ -736,10 +746,11 @@ final class _ActiveRustStreamingIteration {
736746
sync.logger.warning('Could not prefetch credentials', e, s);
737747
});
738748
}
739-
case CloseSyncStream():
749+
case CloseSyncStream(:final hideDisconnect):
740750
if (!sync.aborted) {
741751
_isActive = false;
742-
sync._nonLineSyncEvents.add(const AbortCurrentIteration());
752+
sync._nonLineSyncEvents
753+
.add(AbortCurrentIteration(hideDisconnectState: hideDisconnect));
743754
}
744755
case FlushFileSystem():
745756
await sync.adapter.flushFileSystem();
@@ -751,6 +762,8 @@ final class _ActiveRustStreamingIteration {
751762
}
752763
}
753764

765+
typedef RustSyncIterationResult = ({bool immediateRestart});
766+
754767
sealed class SyncEvent {}
755768

756769
final class ReceivedLine implements SyncEvent {
@@ -768,7 +781,14 @@ final class TokenRefreshComplete implements SyncEvent {
768781
}
769782

770783
final class AbortCurrentIteration implements SyncEvent {
771-
const AbortCurrentIteration();
784+
/// Whether we should immediately disconnect and hide the `disconnected`
785+
/// state.
786+
///
787+
/// This is used when we're changing subscription, to hide the brief downtime
788+
/// we have while reconnecting.
789+
final bool hideDisconnectState;
790+
791+
const AbortCurrentIteration({this.hideDisconnectState = false});
772792
}
773793

774794
final class HandleChangedSubscriptions implements SyncEvent {

packages/powersync_core/lib/src/web/sync_worker.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ class _SyncRunner {
229229
final before = currentStreams.toSet();
230230
final after = connections.values.flattenedToSet;
231231
if (!const SetEquality<SubscribedStream>().equals(before, after)) {
232+
_logger.info(
233+
'Subscriptions across tabs have changed, checking whether a reconnect is necessary');
232234
currentStreams = after.toList();
233235
sync?.updateSubscriptions(currentStreams);
234236
}
@@ -320,6 +322,7 @@ class _SyncRunner {
320322
client: BrowserClient(),
321323
identifier: identifier,
322324
activeSubscriptions: currentStreams,
325+
logger: _logger,
323326
);
324327
sync!.statusStream.listen((event) {
325328
_logger.fine('Broadcasting sync event: $event');

0 commit comments

Comments
 (0)