4
4
library ;
5
5
6
6
import 'dart:async' ;
7
+ import 'dart:convert' ;
7
8
import 'dart:js_interop' ;
8
9
9
10
import 'package:async/async.dart' ;
@@ -41,12 +42,15 @@ class _SyncWorker {
41
42
});
42
43
}
43
44
44
- _SyncRunner referenceSyncTask (String databaseIdentifier,
45
- int crudThrottleTimeMs, _ConnectedClient client) {
45
+ _SyncRunner referenceSyncTask (
46
+ String databaseIdentifier,
47
+ int crudThrottleTimeMs,
48
+ String ? syncParamsEncoded,
49
+ _ConnectedClient client) {
46
50
return _requestedSyncTasks.putIfAbsent (databaseIdentifier, () {
47
- return _SyncRunner (databaseIdentifier, crudThrottleTimeMs );
51
+ return _SyncRunner (databaseIdentifier);
48
52
})
49
- ..registerClient (client);
53
+ ..registerClient (client, crudThrottleTimeMs, syncParamsEncoded );
50
54
}
51
55
}
52
56
@@ -64,11 +68,11 @@ class _ConnectedClient {
64
68
switch (type) {
65
69
case SyncWorkerMessageType .startSynchronization:
66
70
final request = payload as StartSynchronization ;
67
- _runner = _worker.referenceSyncTask (
68
- request.databaseName , request.crudThrottleTimeMs , this );
71
+ _runner = _worker.referenceSyncTask (request.databaseName,
72
+ request.crudThrottleTimeMs , request.syncParamsEncoded , this );
69
73
return (JSObject (), null );
70
74
case SyncWorkerMessageType .abortSynchronization:
71
- _runner? .unregisterClient (this );
75
+ _runner? .disconnectClient (this );
72
76
_runner = null ;
73
77
return (JSObject (), null );
74
78
default :
@@ -105,7 +109,8 @@ class _ConnectedClient {
105
109
106
110
class _SyncRunner {
107
111
final String identifier;
108
- final int crudThrottleTimeMs;
112
+ int crudThrottleTimeMs = 1 ;
113
+ String ? syncParamsEncoded;
109
114
110
115
final StreamGroup <_RunnerEvent > _group = StreamGroup ();
111
116
final StreamController <_RunnerEvent > _mainEvents = StreamController ();
@@ -114,24 +119,46 @@ class _SyncRunner {
114
119
_ConnectedClient ? databaseHost;
115
120
final connections = < _ConnectedClient > [];
116
121
117
- _SyncRunner (this .identifier, this .crudThrottleTimeMs ) {
122
+ _SyncRunner (this .identifier) {
118
123
_group.add (_mainEvents.stream);
119
124
120
125
Future (() async {
121
126
await for (final event in _group.stream) {
122
127
try {
123
128
switch (event) {
124
- case _AddConnection (: final client):
129
+ case _AddConnection (
130
+ : final client,
131
+ : final crudThrottleTimeMs,
132
+ : final syncParamsEncoded
133
+ ):
125
134
connections.add (client);
135
+ var reconnect = false ;
136
+ if (this .crudThrottleTimeMs != crudThrottleTimeMs) {
137
+ this .crudThrottleTimeMs = crudThrottleTimeMs;
138
+ reconnect = true ;
139
+ }
140
+ if (this .syncParamsEncoded != syncParamsEncoded) {
141
+ this .syncParamsEncoded = syncParamsEncoded;
142
+ reconnect = true ;
143
+ }
126
144
if (sync == null ) {
127
145
await _requestDatabase (client);
146
+ } else if (reconnect) {
147
+ // Parameters changed - reconnect.
148
+ sync ? .abort ();
149
+ sync = null ;
150
+ await _requestDatabase (client);
128
151
}
129
152
case _RemoveConnection (: final client):
130
153
connections.remove (client);
131
154
if (connections.isEmpty) {
132
155
await sync ? .abort ();
133
156
sync = null ;
134
157
}
158
+ case _DisconnectClient (: final client):
159
+ connections.remove (client);
160
+ await sync ? .abort ();
161
+ sync = null ;
135
162
case _ActiveDatabaseClosed ():
136
163
_logger.info ('Remote database closed, finding a new client' );
137
164
sync ? .abort ();
@@ -226,16 +253,20 @@ class _SyncRunner {
226
253
);
227
254
}
228
255
256
+ final syncParams = syncParamsEncoded == null
257
+ ? null
258
+ : jsonDecode (syncParamsEncoded! ) as Map <String , dynamic >;
259
+
229
260
sync = StreamingSyncImplementation (
230
- adapter: BucketStorage (database),
231
- credentialsCallback: client.channel.credentialsCallback,
232
- invalidCredentialsCallback: client.channel.invalidCredentialsCallback,
233
- uploadCrud: client.channel.uploadCrud,
234
- crudUpdateTriggerStream: crudStream,
235
- retryDelay: Duration (seconds: 3 ),
236
- client: FetchClient (mode: RequestMode .cors),
237
- identifier: identifier,
238
- );
261
+ adapter: BucketStorage (database),
262
+ credentialsCallback: client.channel.credentialsCallback,
263
+ invalidCredentialsCallback: client.channel.invalidCredentialsCallback,
264
+ uploadCrud: client.channel.uploadCrud,
265
+ crudUpdateTriggerStream: crudStream,
266
+ retryDelay: Duration (seconds: 3 ),
267
+ client: FetchClient (mode: RequestMode .cors),
268
+ identifier: identifier,
269
+ syncParameters : syncParams );
239
270
sync ! .statusStream.listen ((event) {
240
271
_logger.fine ('Broadcasting sync event: $event ' );
241
272
for (final client in connections) {
@@ -246,21 +277,31 @@ class _SyncRunner {
246
277
sync ! .streamingSync ();
247
278
}
248
279
249
- void registerClient (_ConnectedClient client) {
250
- _mainEvents.add (_AddConnection (client));
280
+ void registerClient (_ConnectedClient client, int currentCrudThrottleTimeMs,
281
+ String ? currentSyncParamsEncoded) {
282
+ _mainEvents.add (_AddConnection (
283
+ client, currentCrudThrottleTimeMs, currentSyncParamsEncoded));
251
284
}
252
285
286
+ /// Remove a client, disconnecting if no clients remain..
253
287
void unregisterClient (_ConnectedClient client) {
254
288
_mainEvents.add (_RemoveConnection (client));
255
289
}
290
+
291
+ /// Remove a client, and immediately disconnect.
292
+ void disconnectClient (_ConnectedClient client) {
293
+ _mainEvents.add (_DisconnectClient (client));
294
+ }
256
295
}
257
296
258
297
sealed class _RunnerEvent {}
259
298
260
299
final class _AddConnection implements _RunnerEvent {
261
300
final _ConnectedClient client;
301
+ final int crudThrottleTimeMs;
302
+ final String ? syncParamsEncoded;
262
303
263
- _AddConnection (this .client);
304
+ _AddConnection (this .client, this .crudThrottleTimeMs, this .syncParamsEncoded );
264
305
}
265
306
266
307
final class _RemoveConnection implements _RunnerEvent {
@@ -269,6 +310,12 @@ final class _RemoveConnection implements _RunnerEvent {
269
310
_RemoveConnection (this .client);
270
311
}
271
312
313
+ final class _DisconnectClient implements _RunnerEvent {
314
+ final _ConnectedClient client;
315
+
316
+ _DisconnectClient (this .client);
317
+ }
318
+
272
319
final class _ActiveDatabaseClosed implements _RunnerEvent {
273
320
const _ActiveDatabaseClosed ();
274
321
}
0 commit comments