Skip to content

Commit

Permalink
Merge pull request #1761 from matthiasn/feat/continue_when_file_missing
Browse files Browse the repository at this point in the history
feat: increment retry count when failing
  • Loading branch information
matthiasn committed Jun 3, 2024
2 parents dbacc7c + 437114a commit 2d2660c
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 121 deletions.
1 change: 1 addition & 0 deletions integration_test/matrix_service_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:lotti/database/settings_db.dart';
import 'package:lotti/get_it.dart';
import 'package:lotti/services/db_notification.dart';
import 'package:lotti/sync/matrix/matrix_service.dart';
import 'package:lotti/sync/matrix/send_message.dart';
import 'package:lotti/sync/secure_storage.dart';
import 'package:lotti/sync/vector_clock.dart';
import 'package:lotti/utils/file_utils.dart';
Expand Down
13 changes: 0 additions & 13 deletions lib/sync/matrix/matrix_service.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import 'dart:async';

import 'package:lotti/classes/config.dart';
import 'package:lotti/classes/sync_message.dart';
import 'package:lotti/database/database.dart';
import 'package:lotti/sync/client_runner.dart';
import 'package:lotti/sync/matrix/client.dart';
import 'package:lotti/sync/matrix/config.dart';
import 'package:lotti/sync/matrix/key_verification_runner.dart';
import 'package:lotti/sync/matrix/last_read.dart';
import 'package:lotti/sync/matrix/room.dart';
import 'package:lotti/sync/matrix/send_message.dart';
import 'package:lotti/sync/matrix/stats.dart';
import 'package:lotti/sync/matrix/timeline.dart';
import 'package:matrix/encryption/utils/key_verification.dart';
Expand Down Expand Up @@ -178,17 +176,6 @@ class MatrixService {
Future<void> startKeyVerificationListener() =>
listenForKeyVerificationRequests(service: this);

Future<bool> sendMatrixMsg(
SyncMessage syncMessage, {
String? myRoomId,
}) async {
return sendMessage(
syncMessage,
service: this,
myRoomId: myRoomId,
);
}

Future<void> logout() async {
if (_client.isLogged()) {
timeline?.cancelSubscriptions();
Expand Down
150 changes: 64 additions & 86 deletions lib/sync/matrix/send_message.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/classes/sync_message.dart';
import 'package:lotti/database/database.dart';
Expand All @@ -16,42 +16,39 @@ import 'package:lotti/utils/file_utils.dart';
import 'package:lotti/utils/image_utils.dart';
import 'package:matrix/matrix.dart';

/// Sends a Matrix message for cross-device state synchronization. Takes a
/// [SyncMessage] and also requires the system's [MatrixService]. A room can
/// optionally be specified, e.g. in testing. Otherwise, the service's `syncRoom`
/// is used.
/// Also updates some stats on sent message counts on the [service].
/// The send function will terminate early (and thus refuse to send anything)
/// when there are users with unverified device in the room.
Future<bool> sendMessage(
SyncMessage syncMessage, {
required MatrixService service,
required String? myRoomId,
}) async {
final loggingDb = getIt<LoggingDb>();

try {
extension SendExtension on MatrixService {
void incrementSentCount() {
sentCount = sentCount + 1;
messageCountsController.add(
MatrixStats(
messageCounts: messageCounts,
sentCount: sentCount,
),
);
}

/// Sends a Matrix message for cross-device state synchronization. Takes a
/// [SyncMessage] and also requires the system's [MatrixService]. A room can
/// optionally be specified, e.g. in testing. Otherwise, the service's `syncRoom`
/// is used.
/// Also updates some stats on sent message counts on the [MatrixService].
/// The send function will terminate early (and thus refuse to send anything)
/// when there are users with unverified device in the room.
Future<void> sendMatrixMsg(
SyncMessage syncMessage, {
String? myRoomId,
}) async {
final loggingDb = getIt<LoggingDb>();

final msg = json.encode(syncMessage);
final syncRoom = service.syncRoom;
final roomId = myRoomId ?? service.syncRoomId;

void incrementSentCount() {
service.sentCount = service.sentCount + 1;
service.messageCountsController.add(
MatrixStats(
messageCounts: service.messageCounts,
sentCount: service.sentCount,
),
);
}
final roomId = myRoomId ?? syncRoomId;

if (service.getUnverifiedDevices().isNotEmpty) {
if (getUnverifiedDevices().isNotEmpty) {
loggingDb.captureException(
'Unverified devices found',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);
return false;
}

if (roomId == null) {
Expand All @@ -60,7 +57,6 @@ Future<bool> sendMessage(
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);
return false;
}

loggingDb.captureEvent(
Expand Down Expand Up @@ -96,77 +92,59 @@ Future<bool> sendMessage(
journalAudio: (JournalAudio journalAudio) async {
if (shouldResendAttachments ||
syncMessage.status == SyncEntryStatus.initial) {
final relativePath = AudioUtils.getRelativeAudioPath(journalAudio);
final fullPath = AudioUtils.getAudioPath(journalAudio, docDir);
final bytes = await File(fullPath).readAsBytes();

loggingDb.captureEvent(
'trying to send $relativePath file message to $syncRoom',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);
final eventId = await syncRoom?.sendFileEvent(
MatrixFile(
bytes: bytes,
name: fullPath,
unawaited(
sendFile(
fullPath: AudioUtils.getAudioPath(
journalAudio,
docDir,
),
relativePath: AudioUtils.getRelativeAudioPath(journalAudio),
),
extraContent: {
'relativePath': relativePath,
},
);
incrementSentCount();

loggingDb.captureEvent(
'sent $relativePath file message to $syncRoom, event ID $eventId',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);
}
},
journalImage: (JournalImage journalImage) async {
if (shouldResendAttachments ||
syncMessage.status == SyncEntryStatus.initial) {
final relativePath = getRelativeImagePath(journalImage);
final fullPath = getFullImagePath(journalImage);
final bytes = await File(fullPath).readAsBytes();

loggingDb.captureEvent(
'trying to send $relativePath file message to $syncRoom',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);

final eventId = await syncRoom?.sendFileEvent(
MatrixFile(
bytes: bytes,
name: fullPath,
unawaited(
sendFile(
fullPath: getFullImagePath(journalImage),
relativePath: getRelativeImagePath(journalImage),
),
extraContent: {
'relativePath': relativePath,
},
);

incrementSentCount();

loggingDb.captureEvent(
'sent $relativePath file message to $syncRoom, event ID $eventId',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);
}
},
orElse: () {},
);
}
return true;
} catch (e, stackTrace) {
debugPrint('MATRIX: Error sending message: $e');
loggingDb.captureException(
e,
}

/// Sends a file attachment to the sync room.
Future<void> sendFile({
required String fullPath,
required String relativePath,
}) async {
final loggingDb = getIt<LoggingDb>()
..captureEvent(
'trying to send $relativePath file message to $syncRoom',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
);

final eventId = await syncRoom?.sendFileEvent(
MatrixFile(
bytes: await File(fullPath).readAsBytes(),
name: fullPath,
),
extraContent: {'relativePath': relativePath},
);

incrementSentCount();

loggingDb.captureEvent(
'sent $relativePath file message to $syncRoom, event ID $eventId',
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
stackTrace: stackTrace,
);
}
return false;
}
43 changes: 22 additions & 21 deletions lib/sync/outbox/outbox_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:lotti/get_it.dart';
import 'package:lotti/services/vector_clock_service.dart';
import 'package:lotti/sync/client_runner.dart';
import 'package:lotti/sync/matrix/matrix_service.dart';
import 'package:lotti/sync/matrix/send_message.dart';
import 'package:lotti/utils/audio_utils.dart';
import 'package:lotti/utils/consts.dart';
import 'package:lotti/utils/file_utils.dart';
Expand Down Expand Up @@ -140,36 +141,36 @@ class OutboxService {
);

try {
final syncMessage = SyncMessage.fromJson(
json.decode(nextPending.message) as Map<String, dynamic>,
await getIt<MatrixService>().sendMatrixMsg(
SyncMessage.fromJson(
json.decode(nextPending.message) as Map<String, dynamic>,
),
);

final success =
await getIt<MatrixService>().sendMatrixMsg(syncMessage);

if (success) {
await _syncDatabase.updateOutboxItem(
OutboxCompanion(
id: Value(nextPending.id),
status: Value(OutboxStatus.sent.index),
updatedAt: Value(DateTime.now()),
),
);
if (unprocessed.length > 1) {
await enqueueNextSendRequest();
}
} else {
await enqueueNextSendRequest(
delay: const Duration(seconds: 15),
);
await _syncDatabase.updateOutboxItem(
OutboxCompanion(
id: Value(nextPending.id),
status: Value(OutboxStatus.sent.index),
updatedAt: Value(DateTime.now()),
),
);
if (unprocessed.length > 1) {
await enqueueNextSendRequest();
}

_loggingDb.captureEvent(
'${nextPending.subject} done',
domain: 'OUTBOX',
subDomain: 'sendNext()',
);
} catch (e) {
} catch (e, stackTrace) {
getIt<LoggingDb>().captureException(
e,
domain: 'MATRIX_SERVICE',
subDomain: 'sendMatrixMsg',
stackTrace: stackTrace,
);

await _syncDatabase.updateOutboxItem(
OutboxCompanion(
id: Value(nextPending.id),
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: lotti
description: Achieve your goals and keep your data private with Lotti.
publish_to: 'none'
version: 0.9.472+2542
version: 0.9.473+2543

msix_config:
display_name: LottiApp
Expand Down

0 comments on commit 2d2660c

Please sign in to comment.