Skip to content

Commit 45853a6

Browse files
committed
Retry if api call failed and prevent race conditions
1 parent 286499d commit 45853a6

File tree

1 file changed

+51
-27
lines changed

1 file changed

+51
-27
lines changed

lib/config/providers/chat_provider.dart

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import 'package:whitenoise/utils/pubkey_formatter.dart';
2525
class ChatNotifier extends Notifier<ChatState> {
2626
final _logger = Logger('ChatNotifier');
2727
final _messageSenderService = MessageSenderService();
28+
29+
final Map<String, Future<DMChatData?>> _dmChatDataLoadingFutures = {};
2830

2931
@override
3032
ChatState build() {
@@ -758,10 +760,17 @@ class ChatNotifier extends Notifier<ChatState> {
758760
return state.getDMChatData(groupId);
759761
}
760762

763+
if (_dmChatDataLoadingFutures.containsKey(groupId)) {
764+
return _dmChatDataLoadingFutures[groupId];
765+
}
766+
761767
// Load data asynchronously and cache it
762768
try {
763769
_logger.info('Loading DMChatData for group: $groupId');
764-
final dmChatData = await _loadDMChatData(groupId);
770+
final future = _loadDMChatData(groupId);
771+
_dmChatDataLoadingFutures[groupId] = future;
772+
final dmChatData = await future;
773+
_dmChatDataLoadingFutures.remove(groupId);
765774

766775
// Update state with cached data
767776
state = state.copyWith(
@@ -774,6 +783,7 @@ class ChatNotifier extends Notifier<ChatState> {
774783
return dmChatData;
775784
} catch (e, st) {
776785
_logger.severe('Failed to load DMChatData for group $groupId', e, st);
786+
_dmChatDataLoadingFutures.remove(groupId);
777787
// Cache null result to avoid repeated failed attempts
778788
state = state.copyWith(
779789
dmChatDataCache: {
@@ -806,35 +816,49 @@ class ChatNotifier extends Notifier<ChatState> {
806816
}
807817
}
808818

809-
/// Helper method to load DMChatData using the NotifierProviderRef
819+
/// Helper method to load DMChatData using the NotifierProviderRef with retry strategy
810820
Future<DMChatData?> _loadDMChatData(String groupId) async {
811-
try {
812-
final otherMember = ref.read(groupsProvider.notifier).getOtherGroupMember(groupId);
813-
814-
if (otherMember != null) {
815-
final user = await wn_users_api.getUser(pubkey: otherMember.publicKey);
816-
final otherMemberPubkey = otherMember.publicKey;
817-
final otherMemberNpubPubkey = PubkeyFormatter(pubkey: otherMemberPubkey).toNpub() ?? '';
818-
final userProfile = UserProfile.fromMetadata(
819-
pubkey: otherMemberNpubPubkey,
820-
metadata: user.metadata,
821-
);
822-
final displayName = userProfile.displayName;
823-
final displayImage = userProfile.imagePath ?? (otherMember.imagePath ?? '');
824-
final nip05 = userProfile.nip05 ?? '';
825-
final npub = userProfile.publicKey;
826-
return DMChatData(
827-
displayName: displayName,
828-
displayImage: displayImage,
829-
nip05: nip05,
830-
publicKey: npub,
831-
);
832-
}
821+
const maxRetries = 2;
822+
int attempt = 0;
823+
824+
while (attempt <= maxRetries) {
825+
try {
826+
final otherMember = ref.read(groupsProvider.notifier).getOtherGroupMember(groupId);
827+
828+
if (otherMember != null) {
829+
final user = await wn_users_api.getUser(pubkey: otherMember.publicKey);
830+
final otherMemberPubkey = otherMember.publicKey;
831+
final otherMemberNpubPubkey = PubkeyFormatter(pubkey: otherMemberPubkey).toNpub() ?? '';
832+
final userProfile = UserProfile.fromMetadata(
833+
pubkey: otherMemberNpubPubkey,
834+
metadata: user.metadata,
835+
);
836+
final displayName = userProfile.displayName;
837+
final displayImage = userProfile.imagePath ?? (otherMember.imagePath ?? '');
838+
final nip05 = userProfile.nip05 ?? '';
839+
final npub = userProfile.publicKey;
840+
return DMChatData(
841+
displayName: displayName,
842+
displayImage: displayImage,
843+
nip05: nip05,
844+
publicKey: npub,
845+
);
846+
}
833847

834-
return null;
835-
} catch (e) {
836-
return null;
848+
return null;
849+
} catch (e) {
850+
attempt++;
851+
if (attempt <= maxRetries) {
852+
_logger.warning('Error in _loadDMChatData for group $groupId (attempt $attempt/$maxRetries): $e');
853+
await Future.delayed(Duration(milliseconds: 500 * attempt));
854+
} else {
855+
_logger.severe('Failed to load DMChatData for group $groupId after $maxRetries retries: $e');
856+
return null;
857+
}
858+
}
837859
}
860+
861+
return null;
838862
}
839863
}
840864

0 commit comments

Comments
 (0)