Merge branch 'Bubu/clear_cache' into 'main'

fix: clear cache

See merge request famedly/famedlysdk!567
This commit is contained in:
Marcus 2020-12-22 16:38:10 +00:00
commit 294d82752a
5 changed files with 73 additions and 25 deletions

View File

@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import 'basic_event.dart';
import 'basic_event_with_sender.dart'; import 'basic_event_with_sender.dart';
import 'basic_room_event.dart'; import 'basic_room_event.dart';
import 'stripped_state_event.dart';
import 'matrix_event.dart'; import 'matrix_event.dart';
import 'basic_event.dart';
import 'presence.dart'; import 'presence.dart';
import 'room_summary.dart'; import 'room_summary.dart';
import 'stripped_state_event.dart';
class SyncUpdate { class SyncUpdate {
String nextBatch; String nextBatch;

View File

@ -25,13 +25,13 @@ import 'package:http/http.dart' as http;
import '../encryption.dart'; import '../encryption.dart';
import '../famedlysdk.dart'; import '../famedlysdk.dart';
import '../matrix_api/utils/logs.dart';
import 'database/database.dart' show Database; import 'database/database.dart' show Database;
import 'event.dart'; import 'event.dart';
import 'room.dart'; import 'room.dart';
import 'user.dart'; import 'user.dart';
import 'utils/device_keys_list.dart'; import 'utils/device_keys_list.dart';
import 'utils/event_update.dart'; import 'utils/event_update.dart';
import '../matrix_api/utils/logs.dart';
import 'utils/matrix_file.dart'; import 'utils/matrix_file.dart';
import 'utils/room_update.dart'; import 'utils/room_update.dart';
import 'utils/to_device_event.dart'; import 'utils/to_device_event.dart';
@ -46,10 +46,16 @@ enum LoginState { logged, loggedOut }
/// SDK. /// SDK.
class Client extends MatrixApi { class Client extends MatrixApi {
int _id; int _id;
// Keeps track of the currently ongoing syncRequest
// in case we want to cancel it.
int _currentSyncId;
int get id => _id; int get id => _id;
final FutureOr<Database> Function(Client) databaseBuilder; final FutureOr<Database> Function(Client) databaseBuilder;
Database _database; Database _database;
Database get database => _database; Database get database => _database;
bool enableE2eeRecovery; bool enableE2eeRecovery;
@ -153,6 +159,7 @@ class Client extends MatrixApi {
bool get fileEncryptionEnabled => encryptionEnabled && true; bool get fileEncryptionEnabled => encryptionEnabled && true;
String get identityKey => encryption?.identityKey ?? ''; String get identityKey => encryption?.identityKey ?? '';
String get fingerprintKey => encryption?.fingerprintKey ?? ''; String get fingerprintKey => encryption?.fingerprintKey ?? '';
/// Wheather this session is unknown to others /// Wheather this session is unknown to others
@ -585,14 +592,17 @@ class Client extends MatrixApi {
final StreamController<LoginState> onLoginStateChanged = final StreamController<LoginState> onLoginStateChanged =
StreamController.broadcast(); StreamController.broadcast();
/// Synchronization erros are coming here. /// Called when the local cache is reset
final StreamController<bool> onCacheCleared = StreamController.broadcast();
/// Synchronization errors are coming here.
final StreamController<SdkError> onSyncError = StreamController.broadcast(); final StreamController<SdkError> onSyncError = StreamController.broadcast();
/// Encryption erros are coming here. /// Encryption errors are coming here.
final StreamController<SdkError> onEncryptionError = final StreamController<SdkError> onEncryptionError =
StreamController.broadcast(); StreamController.broadcast();
/// This is called once, when the first sync has received. /// This is called once, when the first sync has been processed.
final StreamController<bool> onFirstSync = StreamController.broadcast(); final StreamController<bool> onFirstSync = StreamController.broadcast();
/// When a new sync response is coming in, this gives the complete payload. /// When a new sync response is coming in, this gives the complete payload.
@ -808,6 +818,7 @@ class Client extends MatrixApi {
bool _backgroundSync = true; bool _backgroundSync = true;
Future<void> _currentSync, _retryDelay = Future.value(); Future<void> _currentSync, _retryDelay = Future.value();
bool get syncPending => _currentSync != null; bool get syncPending => _currentSync != null;
/// Controls the background sync (automatically looping forever if turned on). /// Controls the background sync (automatically looping forever if turned on).
@ -843,15 +854,19 @@ class Client extends MatrixApi {
Future<void> _innerSync() async { Future<void> _innerSync() async {
await _retryDelay; await _retryDelay;
_retryDelay = Future.delayed(Duration(seconds: syncErrorTimeoutSec)); _retryDelay = Future.delayed(Duration(seconds: syncErrorTimeoutSec));
if (!isLogged() || _disposed) return null; if (!isLogged() || _disposed || _aborted) return null;
try { try {
final syncResp = await sync( final syncRequest = sync(
filter: syncFilters, filter: syncFilters,
since: prevBatch, since: prevBatch,
timeout: prevBatch != null ? 30000 : null, timeout: prevBatch != null ? 30000 : null,
setPresence: syncPresence, setPresence: syncPresence,
); );
if (_disposed) return; _currentSyncId = syncRequest.hashCode;
final syncResp = await syncRequest;
if (_currentSyncId != syncRequest.hashCode) {
return;
}
if (database != null) { if (database != null) {
_currentTransaction = database.transaction(() async { _currentTransaction = database.transaction(() async {
await handleSync(syncResp); await handleSync(syncResp);
@ -863,7 +878,7 @@ class Client extends MatrixApi {
} else { } else {
await handleSync(syncResp); await handleSync(syncResp);
} }
if (_disposed) return; if (_disposed || _aborted) return;
if (prevBatch == null) { if (prevBatch == null) {
onFirstSync.add(true); onFirstSync.add(true);
prevBatch = syncResp.nextBatch; prevBatch = syncResp.nextBatch;
@ -887,7 +902,7 @@ class Client extends MatrixApi {
Logs().w('Synchronization connection failed', e); Logs().w('Synchronization connection failed', e);
onSyncError.add(SdkError(exception: e, stackTrace: s)); onSyncError.add(SdkError(exception: e, stackTrace: s));
} catch (e, s) { } catch (e, s) {
if (!isLogged() || _disposed) return; if (!isLogged() || _disposed || _aborted) return;
Logs().e('Error during processing events', e, s); Logs().e('Error during processing events', e, s);
onSyncError.add(SdkError( onSyncError.add(SdkError(
exception: e is Exception ? e : Exception(e), stackTrace: s)); exception: e is Exception ? e : Exception(e), stackTrace: s));
@ -1349,6 +1364,7 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
} }
final Map<String, DateTime> _keyQueryFailures = {}; final Map<String, DateTime> _keyQueryFailures = {};
Future<void> _updateUserDeviceKeys() async { Future<void> _updateUserDeviceKeys() async {
try { try {
if (!isLogged()) return; if (!isLogged()) return;
@ -1654,11 +1670,21 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
} }
} }
/// Clear all local cached messages and perform a new clean sync. @Deprecated('Use clearCache()')
Future<void> clearLocalCachedMessages() async { Future<void> clearLocalCachedMessages() async {
await clearCache();
}
/// Clear all local cached messages, room information and outbound group
/// sessions and perform a new clean sync.
Future<void> clearCache() async {
await abortSync();
prevBatch = null; prevBatch = null;
rooms.forEach((r) => r.prev_batch = null); rooms.clear();
await database?.clearCache(id); await database?.clearCache(id);
onCacheCleared.add(true);
// Restart the syncloop
backgroundSync = true;
} }
/// A list of mxids of users who are ignored. /// A list of mxids of users who are ignored.
@ -1679,7 +1705,7 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
'ignored_users': Map.fromEntries( 'ignored_users': Map.fromEntries(
(ignoredUsers..add(userId)).map((key) => MapEntry(key, {}))), (ignoredUsers..add(userId)).map((key) => MapEntry(key, {}))),
}); });
await clearLocalCachedMessages(); await clearCache();
return; return;
} }
@ -1696,22 +1722,35 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
'ignored_users': Map.fromEntries( 'ignored_users': Map.fromEntries(
(ignoredUsers..remove(userId)).map((key) => MapEntry(key, {}))), (ignoredUsers..remove(userId)).map((key) => MapEntry(key, {}))),
}); });
await clearLocalCachedMessages(); await clearCache();
return; return;
} }
bool _disposed = false; bool _disposed = false;
bool _aborted = false;
Future _currentTransaction = Future.sync(() => {}); Future _currentTransaction = Future.sync(() => {});
/// Stops the synchronization and closes the database. After this /// Blackholes any ongoing sync call. Currently ongoing sync *processing* is
/// you can safely make this Client instance null. /// still going to be finished, new data is ignored.
Future<void> dispose({bool closeDatabase = true}) async { Future<void> abortSync() async {
_disposed = true; _aborted = true;
backgroundSync = false;
_currentSyncId = -1;
try { try {
await _currentTransaction; await _currentTransaction;
} catch (_) { } catch (_) {
// No-OP // No-OP
} }
_currentSync = null;
// reset _aborted for being able to restart the sync.
_aborted = false;
}
/// Stops the synchronization and closes the database. After this
/// you can safely make this Client instance null.
Future<void> dispose({bool closeDatabase = true}) async {
_disposed = true;
await abortSync();
encryption?.dispose(); encryption?.dispose();
encryption = null; encryption = null;
try { try {
@ -1731,5 +1770,6 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
class SdkError { class SdkError {
Exception exception; Exception exception;
StackTrace stackTrace; StackTrace stackTrace;
SdkError({this.exception, this.stackTrace}); SdkError({this.exception, this.stackTrace});
} }

View File

@ -6,9 +6,9 @@ import 'package:olm/olm.dart' as olm;
import '../../famedlysdk.dart' as sdk; import '../../famedlysdk.dart' as sdk;
import '../../matrix_api.dart' as api; import '../../matrix_api.dart' as api;
import '../../matrix_api/utils/logs.dart';
import '../client.dart'; import '../client.dart';
import '../room.dart'; import '../room.dart';
import '../../matrix_api/utils/logs.dart';
part 'database.g.dart'; part 'database.g.dart';
@ -633,6 +633,7 @@ class Database extends _$Database {
await (delete(outboundGroupSessions) await (delete(outboundGroupSessions)
..where((r) => r.clientId.equals(clientId))) ..where((r) => r.clientId.equals(clientId)))
.go(); .go();
_ensuredRooms.clear();
await storePrevBatch(null, clientId); await storePrevBatch(null, clientId);
} }

View File

@ -21,18 +21,18 @@ import 'dart:typed_data';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/matrix_api/utils/logs.dart';
import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/utils/event_update.dart'; import 'package:famedlysdk/src/utils/event_update.dart';
import 'package:famedlysdk/matrix_api/utils/logs.dart';
import 'package:famedlysdk/src/utils/room_update.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart'; import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:famedlysdk/src/utils/room_update.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'fake_matrix_api.dart';
import 'fake_database.dart';
import 'fake_client.dart'; import 'fake_client.dart';
import 'fake_database.dart';
import 'fake_matrix_api.dart';
void main() { void main() {
Client matrix; Client matrix;
@ -487,6 +487,12 @@ void main() {
expect(Room(id: '!room1') == 'beep', false); expect(Room(id: '!room1') == 'beep', false);
}); });
test('clearCache', () async {
final client = await getClient();
client.backgroundSync = true;
await client.clearCache();
});
test('dispose', () async { test('dispose', () async {
await matrix.dispose(closeDatabase: true); await matrix.dispose(closeDatabase: true);
}); });

View File

@ -17,10 +17,11 @@
*/ */
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/matrix_api/model/matrix_keys.dart';
import 'package:famedlysdk/matrix_api/model/filter.dart'; import 'package:famedlysdk/matrix_api/model/filter.dart';
import 'package:famedlysdk/matrix_api/model/matrix_exception.dart'; import 'package:famedlysdk/matrix_api/model/matrix_exception.dart';
import 'package:famedlysdk/matrix_api/model/matrix_keys.dart';
import 'package:famedlysdk/matrix_api/model/presence_content.dart'; import 'package:famedlysdk/matrix_api/model/presence_content.dart';
import 'package:famedlysdk/matrix_api/model/push_rule_set.dart'; import 'package:famedlysdk/matrix_api/model/push_rule_set.dart';
import 'package:famedlysdk/matrix_api/model/pusher.dart'; import 'package:famedlysdk/matrix_api/model/pusher.dart';