fix: persistence (#329)
* fix(llc): Save original passed persistence for client reconnection. Signed-off-by: Sahil Kumar <[email protected]> * fix(persistence): Check for empty channels before applying offset Signed-off-by: Sahil Kumar <[email protected]> * fix(llc): Remove debug logs Signed-off-by: Sahil Kumar <[email protected]> * fix(persistence): Reset isolate on successful disconnect Signed-off-by: Sahil Kumar <[email protected]> * use mutexes in persistence client * fix(persistence): use `super.updateChannelStates` Signed-off-by: Sahil Kumar <[email protected]> * fix(persistence): fix database multiple times creation. Signed-off-by: Sahil Kumar <[email protected]> Co-authored-by: Sahil Kumar <[email protected]>
This commit is contained in:
co-authored by
Sahil Kumar
parent
ca1f70948e
commit
9952265109
@@ -7,11 +7,11 @@ import 'package:logging/logging.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:stream_chat/src/api/retry_queue.dart';
|
||||
import 'package:stream_chat/src/event_type.dart';
|
||||
import 'package:stream_chat/src/extensions/rate_limit.dart';
|
||||
import 'package:stream_chat/src/models/attachment_file.dart';
|
||||
import 'package:stream_chat/src/models/channel_state.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat/src/extensions/rate_limit.dart';
|
||||
|
||||
/// This a the class that manages a specific channel.
|
||||
class Channel {
|
||||
@@ -1209,9 +1209,9 @@ class ChannelClientState {
|
||||
ChannelClientState(
|
||||
this._channel,
|
||||
ChannelState channelState,
|
||||
) : _debouncedUpdatePersistenceChannelState = _channel
|
||||
?._client?.chatPersistenceClient?.updateChannelState
|
||||
?.debounced(const Duration(seconds: 1)) {
|
||||
) : _debouncedUpdatePersistenceChannelState = ((ChannelState state) {
|
||||
_channel?._client?.chatPersistenceClient?.updateChannelState(state);
|
||||
}).debounced(const Duration(seconds: 1)) {
|
||||
retryQueue = RetryQueue(
|
||||
channel: _channel,
|
||||
logger: Logger('RETRY QUEUE ${_channel.cid}'),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ignore_for_file: unnecessary_getters_setters
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:stream_chat/src/extensions/map_extension.dart';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@@ -16,6 +17,7 @@ import 'package:stream_chat/src/attachment_file_uploader.dart';
|
||||
import 'package:stream_chat/src/db/chat_persistence_client.dart';
|
||||
import 'package:stream_chat/src/event_type.dart';
|
||||
import 'package:stream_chat/src/exceptions.dart';
|
||||
import 'package:stream_chat/src/extensions/map_extension.dart';
|
||||
import 'package:stream_chat/src/models/attachment_file.dart';
|
||||
import 'package:stream_chat/src/models/channel_model.dart';
|
||||
import 'package:stream_chat/src/models/channel_state.dart';
|
||||
@@ -106,14 +108,22 @@ class StreamChatClient {
|
||||
logger.info('instantiating new client');
|
||||
}
|
||||
|
||||
set chatPersistenceClient(ChatPersistenceClient value) {
|
||||
_originalChatPersistenceClient = value;
|
||||
}
|
||||
|
||||
ChatPersistenceClient _originalChatPersistenceClient;
|
||||
|
||||
/// Chat persistence client
|
||||
ChatPersistenceClient chatPersistenceClient;
|
||||
ChatPersistenceClient get chatPersistenceClient => _chatPersistenceClient;
|
||||
|
||||
ChatPersistenceClient _chatPersistenceClient;
|
||||
|
||||
/// Attachment uploader
|
||||
AttachmentFileUploader attachmentFileUploader;
|
||||
|
||||
/// Whether the chat persistence is available or not
|
||||
bool get persistenceEnabled => chatPersistenceClient != null;
|
||||
bool get persistenceEnabled => _chatPersistenceClient != null;
|
||||
|
||||
RetryPolicy _retryPolicy;
|
||||
|
||||
@@ -357,7 +367,7 @@ class StreamChatClient {
|
||||
|
||||
/// Call this function to dispose the client
|
||||
void dispose() async {
|
||||
await chatPersistenceClient?.disconnect();
|
||||
await _chatPersistenceClient?.disconnect();
|
||||
await _disconnect();
|
||||
httpClient.close();
|
||||
await _controller.close();
|
||||
@@ -446,8 +456,8 @@ class StreamChatClient {
|
||||
|
||||
if (!event.isLocal) {
|
||||
if (_synced && event.createdAt != null) {
|
||||
await chatPersistenceClient?.updateConnectionInfo(event);
|
||||
await chatPersistenceClient?.updateLastSyncAt(event.createdAt);
|
||||
await _chatPersistenceClient?.updateConnectionInfo(event);
|
||||
await _chatPersistenceClient?.updateLastSyncAt(event.createdAt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,8 +488,9 @@ class StreamChatClient {
|
||||
|
||||
_wsConnectionStatus = ConnectionStatus.connecting;
|
||||
|
||||
if (persistenceEnabled) {
|
||||
await chatPersistenceClient.connect(state.user.id);
|
||||
if (_originalChatPersistenceClient != null) {
|
||||
_chatPersistenceClient = _originalChatPersistenceClient;
|
||||
await _chatPersistenceClient.connect(state.user.id);
|
||||
}
|
||||
|
||||
_ws = WebSocket(
|
||||
@@ -508,34 +519,35 @@ class StreamChatClient {
|
||||
),
|
||||
);
|
||||
|
||||
if (status == ConnectionStatus.connected &&
|
||||
state.channels?.isNotEmpty == true) {
|
||||
// ignore: unawaited_futures
|
||||
queryChannelsOnline(filter: {
|
||||
'cid': {
|
||||
'\$in': state.channels.keys.toList(),
|
||||
},
|
||||
}).then(
|
||||
(_) async {
|
||||
await resync();
|
||||
handleEvent(Event(
|
||||
type: EventType.connectionRecovered,
|
||||
online: true,
|
||||
));
|
||||
},
|
||||
);
|
||||
} else {
|
||||
_synced = false;
|
||||
if (status == ConnectionStatus.connected) {
|
||||
handleEvent(Event(
|
||||
type: EventType.connectionRecovered,
|
||||
online: true,
|
||||
));
|
||||
if (state.channels?.isNotEmpty == true) {
|
||||
// ignore: unawaited_futures
|
||||
queryChannelsOnline(filter: {
|
||||
'cid': {
|
||||
'\$in': state.channels.keys.toList(),
|
||||
},
|
||||
}).then(
|
||||
(_) async {
|
||||
await resync();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
_synced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_connectionStatusSubscription =
|
||||
_ws.connectionStatusStream.listen(_connectionStatusHandler);
|
||||
|
||||
var event = await chatPersistenceClient?.getConnectionInfo();
|
||||
var event = await _chatPersistenceClient?.getConnectionInfo();
|
||||
|
||||
await _ws.connect().then((e) async {
|
||||
await chatPersistenceClient?.updateConnectionInfo(e);
|
||||
await _chatPersistenceClient?.updateConnectionInfo(e);
|
||||
event = e;
|
||||
await resync();
|
||||
}).catchError((err, stacktrace) {
|
||||
@@ -551,14 +563,14 @@ class StreamChatClient {
|
||||
|
||||
/// Get the events missed while offline to sync the offline storage
|
||||
Future<void> resync([List<String> cids]) async {
|
||||
final lastSyncAt = await chatPersistenceClient?.getLastSyncAt();
|
||||
final lastSyncAt = await _chatPersistenceClient?.getLastSyncAt();
|
||||
|
||||
if (lastSyncAt == null) {
|
||||
_synced = true;
|
||||
return;
|
||||
}
|
||||
|
||||
cids ??= await chatPersistenceClient?.getChannelCids();
|
||||
cids ??= await _chatPersistenceClient?.getChannelCids();
|
||||
|
||||
if (cids?.isEmpty == true) {
|
||||
return;
|
||||
@@ -586,7 +598,7 @@ class StreamChatClient {
|
||||
|
||||
res.events.forEach(handleEvent);
|
||||
|
||||
await chatPersistenceClient?.updateLastSyncAt(DateTime.now());
|
||||
await _chatPersistenceClient?.updateLastSyncAt(DateTime.now());
|
||||
_synced = true;
|
||||
} catch (error) {
|
||||
logger.severe('Error during resync $error');
|
||||
@@ -723,7 +735,7 @@ class StreamChatClient {
|
||||
|
||||
final updateData = _mapChannelStateToChannel(channels);
|
||||
|
||||
await chatPersistenceClient?.updateChannelQueries(
|
||||
await _chatPersistenceClient?.updateChannelQueries(
|
||||
filter,
|
||||
channels.map((c) => c.channel.cid).toList(),
|
||||
paginationParams?.offset == null || paginationParams.offset == 0,
|
||||
@@ -739,7 +751,7 @@ class StreamChatClient {
|
||||
@required List<SortOption<ChannelModel>> sort,
|
||||
PaginationParams paginationParams = const PaginationParams(),
|
||||
}) async {
|
||||
final offlineChannels = await chatPersistenceClient?.getChannelStates(
|
||||
final offlineChannels = await _chatPersistenceClient?.getChannelStates(
|
||||
filter: filter,
|
||||
sort: sort,
|
||||
paginationParams: paginationParams,
|
||||
@@ -960,8 +972,8 @@ class StreamChatClient {
|
||||
logger.info('Disconnecting flushOfflineStorage: $flushChatPersistence; '
|
||||
'clearUser: $clearUser');
|
||||
|
||||
await chatPersistenceClient?.disconnect(flush: flushChatPersistence);
|
||||
chatPersistenceClient = null;
|
||||
await _chatPersistenceClient?.disconnect(flush: flushChatPersistence);
|
||||
_chatPersistenceClient = null;
|
||||
|
||||
_connectCompleter = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user