eliminate race condition with listen/watch

This commit is contained in:
Christien Rioux 2025-05-18 11:33:08 -04:00
parent 34f9bea6eb
commit 61855521dc
4 changed files with 14 additions and 13 deletions

View file

@ -32,8 +32,7 @@ class MessageReconciliation {
final activeInputQueues = await _updateAuthorInputQueues();
// Process all input queues together
await _outputCubit
.operate((reconciledArray) async => _reconcileInputQueues(
await _outputCubit.operate((reconciledArray) => _reconcileInputQueues(
reconciledArray: reconciledArray,
activeInputQueues: activeInputQueues,
));
@ -273,5 +272,5 @@ class MessageReconciliation {
final TableDBArrayProtobufCubit<proto.ReconciledMessage> _outputCubit;
final void Function(Object, StackTrace?) _onError;
static const int _maxReconcileChunk = 65536;
static const _maxReconcileChunk = 65536;
}

View file

@ -102,7 +102,7 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
}
// Initialize everything
Future<void> _init(Completer<void> _cancel) async {
Future<void> _init(Completer<void> _) async {
_unsentMessagesQueue = PersistentQueue<proto.Message>(
table: 'SingleContactUnsentMessages',
key: _remoteConversationRecordKey.toString(),
@ -126,6 +126,9 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
// Command execution background process
_commandRunnerFut = Future.delayed(Duration.zero, _commandRunner);
// Run reconciliation once for all input queues
_reconciliation.reconcileMessages(null);
}
// Make crypto
@ -198,7 +201,7 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
});
}
Future<VeilidCrypto> _makeLocalMessagesCrypto() async =>
Future<VeilidCrypto> _makeLocalMessagesCrypto() =>
VeilidCryptoPrivate.fromTypedKey(
_accountInfo.userLogin!.identitySecret, 'tabledb');
@ -210,7 +213,7 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
final crypto = await _makeLocalMessagesCrypto();
_reconciledMessagesCubit = TableDBArrayProtobufCubit(
open: () async => TableDBArrayProtobuf.make(
open: () => TableDBArrayProtobuf.make(
table: tableName,
crypto: crypto,
fromBuffer: proto.ReconciledMessage.fromBuffer),

View file

@ -608,14 +608,13 @@ class _DHTLogSpine {
Future<void> watch() async {
// This will update any existing watches if necessary
try {
await _spineRecord.watch(subkeys: [ValueSubkeyRange.single(0)]);
// Update changes to the head record
// xxx: check if this localChanges can be false...
// xxx: Don't watch for local changes because this class already handles
// xxx: notifying listeners and knows when it makes local changes
_subscription ??=
await _spineRecord.listen(localChanges: true, _onSpineChanged);
await _spineRecord.watch(subkeys: [ValueSubkeyRange.single(0)]);
} on Exception {
// If anything fails, try to cancel the watches
await cancelWatch();

View file

@ -482,13 +482,13 @@ class _DHTShortArrayHead {
Future<void> watch() async {
// This will update any existing watches if necessary
try {
await _headRecord.watch(subkeys: [ValueSubkeyRange.single(0)]);
// Update changes to the head record
// Don't watch for local changes because this class already handles
// notifying listeners and knows when it makes local changes
_subscription ??=
await _headRecord.listen(localChanges: false, _onHeadValueChanged);
await _headRecord.watch(subkeys: [ValueSubkeyRange.single(0)]);
} on Exception {
// If anything fails, try to cancel the watches
await cancelWatch();