-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
feat: user sync stream #16862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: user sync stream #16862
Conversation
mobile/lib/infrastructure/repositories/sync_api.repository.dart
Outdated
Show resolved
Hide resolved
4b0957c
to
4d4436f
Compare
04d21e5
to
beecccd
Compare
8f62087
to
0de88c0
Compare
0de88c0
to
edd5cc7
Compare
6d0ba1a
to
b14d61a
Compare
b14d61a
to
afd664d
Compare
Hi @shenlong-tanwen, I added a button to trigger the |
Yes, the only thing that could prevent us from creating another isolate is the |
9ea0265
to
deca45a
Compare
// Wait for the logs to flush | ||
await Future.delayed(const Duration(seconds: 2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there no .flush()
you could call or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one but that can be used only when the logs are buffered. We do not buffer logs on isolates so it is not much useful here. Also, there is an issue with the flush logic currently with how Isar works and so it is disabled for now as well - #16599
DartPluginRegistrant.ensureInitialized(); | ||
|
||
final db = await Bootstrap.initIsar(); | ||
await Bootstrap.initDomain(db, shouldBufferLogs: false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why disable buffering?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On main isolate, we buffer logs and flush them every 5 seconds. However, an isolate does not need to necessarily run for 5 seconds. There is also a chance that an isolate might be killed before the logs are updated, so we disable buffering all together within the isolates
// ignore: avoid-dynamic | ||
final dynamic data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid dynamic to the extent possible. Ideally, only the JSON parsing would involve dynamic, and parse directly into strongly typed objects that share a type (either through an interface, by inheritance or maybe through generics). As it is, dynamic leaks into the events, the response converter map, the main sync handler, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, we went with having strongly typed DTOs initially. But it resulted in us creating a lot of duplicate domain classes that were already available from the OpenAPI generated code. The generated codes are not strongly typed so we do not have a common base class that we could use here.
continue; | ||
} | ||
|
||
if (await _handleSyncData(type, data.map((e) => e.data))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Between the grouping by type, the data mapping here and only the last ack being called, the shape of the sync events seems wrong. Shouldn't the event be a type, an array of data and a single ack to begin with?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each event has a data, it's type and it's ack. If we handle each event separately, we would store and send only the ack of the last successful operation for a particular type, but since we group similar events and handle them in batch, we had to do them this way.
100a1e7
to
6fa44ac
Compare
6fa44ac
to
04e6e56
Compare
* refactor: user entity * chore: rebase fixes * refactor: remove int user Id * refactor: migrate store userId from int to string * refactor: rename uid to id * feat: drift * pr feedback * refactor: move common overrides to mixin * refactor: remove int user Id * refactor: migrate store userId from int to string * refactor: rename uid to id * feat: user & partner sync stream * pr changes * refactor: sync service and add tests * chore: remove generated change * chore: move sync model * rebase: convert string ids to byte uuids * rebase * add processing logs * batch db calls * rewrite isolate manager * rewrite with worker_manager * misc fixes * add sync order test --------- Co-authored-by: shenlong-tanwen <[email protected]> Co-authored-by: Alex <[email protected]>
Description