clear cache fix
This commit is contained in:
parent
0ed5c44919
commit
54fc29f203
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue