Update TouchTokenManager to not cache the tokens

This commit is contained in:
Ming Ming 2022-07-22 16:48:16 +08:00
parent 423d7aa364
commit e5fa14943c
6 changed files with 32 additions and 24 deletions

View file

@ -417,7 +417,7 @@ class ScanAccountDirBloc
Future<List<File>> _queryOnlinePass2(ScanAccountDirBlocQueryBase ev,
Map<int, File> cacheMap, List<File> pass1Files) async {
const touchTokenManager = TouchTokenManager();
final touchTokenManager = TouchTokenManager(_c);
// combine the file maps because [pass1Files] doesn't contain non-supported
// files
final pass2CacheMap = CombinedMapView(
@ -427,8 +427,7 @@ class ScanAccountDirBloc
shouldCheckCache: true,
forwardCacheManager: FileForwardCacheManager(_c, pass2CacheMap),
));
final remoteTouchEtag =
await touchTokenManager.getRemoteRootEtag(fileRepo, account);
final remoteTouchEtag = await touchTokenManager.getRemoteRootEtag(account);
if (remoteTouchEtag == null) {
_log.info("[_queryOnlinePass2] remoteTouchEtag == null");
await touchTokenManager.setLocalRootEtag(account, null);

View file

@ -251,3 +251,8 @@ class DiContainer {
sql.SqliteDb? _sqliteDb;
Pref? _pref;
}
extension DiContainerExtension on DiContainer {
DiContainer withRemoteFileRepo() =>
copyWith(fileRepo: OrNull(fileRepoRemote));
}

View file

@ -469,7 +469,7 @@ class FileCachedDataSource implements FileDataSource {
await FileSqliteCacheUpdater(_c)(account, dir, remote: remote);
if (shouldCheckCache) {
// update our local touch token to match the remote one
const tokenManager = TouchTokenManager();
final tokenManager = TouchTokenManager(_c);
try {
await tokenManager.setLocalToken(
account, dir, cacheLoader.remoteTouchToken);
@ -556,7 +556,7 @@ class FileCachedDataSource implements FileDataSource {
// generate a new random token
final token = const Uuid().v4().replaceAll("-", "");
final dir = File(path: path_lib.dirname(f.path));
await const TouchTokenManager().setLocalToken(account, dir, token);
await TouchTokenManager(_c).setLocalToken(account, dir, token);
// don't update remote token that frequently
(_touchTokenThrottlers["${account.url}/${dir.path}"] ??= Throttler(
onTriggered: _updateRemoteTouchToken,
@ -605,10 +605,8 @@ class FileCachedDataSource implements FileDataSource {
Future<void> _updateRemoteTouchToken(
List<_TouchTokenThrottlerData> data) async {
try {
final fileRepo = FileRepo(this);
final d = data.last;
await const TouchTokenManager()
.setRemoteToken(fileRepo, d.account, d.dir, d.token);
await TouchTokenManager(_c).setRemoteToken(d.account, d.dir, d.token);
} catch (e, stackTrace) {
_log.shout("[_updateRemoteTouchToken] Failed while setRemoteToken", e,
stackTrace);

View file

@ -72,10 +72,10 @@ class FileCacheLoader {
Account account, File f, List<File> cache) async {
final touchPath =
"${remote_storage_util.getRemoteTouchDir(account)}/${f.strippedPath}";
const tokenManager = TouchTokenManager();
final tokenManager = TouchTokenManager(_c);
String? remoteToken;
try {
remoteToken = await tokenManager.getRemoteToken(_c.fileRepo, account, f);
remoteToken = await tokenManager.getRemoteToken(account, f);
} catch (e, stacktrace) {
_log.shout(
"[_checkTouchToken] Failed getting remote token at '$touchPath'",

View file

@ -1,6 +1,5 @@
import 'dart:convert';
import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/di_container.dart';
@ -11,6 +10,7 @@ import 'package:nc_photos/mobile/platform.dart'
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
import 'package:nc_photos/use_case/get_file_binary.dart';
import 'package:nc_photos/use_case/ls_single_file.dart';
import 'package:nc_photos/use_case/put_file_binary.dart';
import 'package:nc_photos/use_case/remove.dart';
@ -23,12 +23,17 @@ import 'package:nc_photos/use_case/remove.dart';
/// token requires downloading a file from the server so you may want to avoid
/// doing it on every query
class TouchTokenManager {
const TouchTokenManager();
TouchTokenManager(this._c) : assert(require(_c));
Future<String?> getRemoteRootEtag(FileRepo fileRepo, Account account) async {
static bool require(DiContainer c) =>
DiContainer.has(c, DiType.fileRepo) &&
DiContainer.has(c, DiType.fileRepoRemote);
Future<String?> getRemoteRootEtag(Account account) async {
try {
final touchDir = await fileRepo.listSingle(
account, File(path: remote_storage_util.getRemoteTouchDir(account)));
// we use the remote repo here to prevent it caching the result
final touchDir = await LsSingleFile(_c.withRemoteFileRepo())(
account, remote_storage_util.getRemoteTouchDir(account));
return touchDir.etag!;
} catch (_) {
// dir not found on server
@ -48,16 +53,14 @@ class TouchTokenManager {
return AccountPref.of(account).getTouchRootEtag();
}
Future<void> setRemoteToken(
FileRepo fileRepo, Account account, File file, String? token) async {
Future<void> setRemoteToken(Account account, File file, String? token) async {
_log.info(
"[setRemoteToken] Set remote token for file '${file.path}': $token");
final path = _getRemotePath(account, file);
if (token == null) {
return Remove(KiwiContainer().resolve<DiContainer>())(account, [file],
shouldCleanUp: false);
return Remove(_c)(account, [file], shouldCleanUp: false);
} else {
return PutFileBinary(fileRepo)(
return PutFileBinary(_c.fileRepo)(
account, path, const Utf8Encoder().convert(token),
shouldCreateMissingDir: true);
}
@ -65,11 +68,11 @@ class TouchTokenManager {
/// Return the touch token for [file] from remote source, or null if no such
/// file
Future<String?> getRemoteToken(
FileRepo fileRepo, Account account, File file) async {
Future<String?> getRemoteToken(Account account, File file) async {
final path = _getRemotePath(account, file);
try {
final content = await GetFileBinary(fileRepo)(account, File(path: path));
final content =
await GetFileBinary(_c.fileRepo)(account, File(path: path));
return const Utf8Decoder().convert(content);
} on ApiException catch (e) {
if (e.response.statusCode == 404) {
@ -114,5 +117,7 @@ class TouchTokenManager {
}
}
final DiContainer _c;
static final _log = Logger("touch_token_manager.TouchTokenManager");
}

View file

@ -53,12 +53,13 @@ class _RootPickerState extends State<RootPicker> {
}
void _initAccount() async {
final c = KiwiContainer().resolve<DiContainer>();
final files = <File>[];
for (final r in widget.account.roots) {
try {
if (r.isNotEmpty) {
_ensureInitDialog();
files.add(await LsSingleFile(KiwiContainer().resolve<DiContainer>())(
files.add(await LsSingleFile(c.withRemoteFileRepo())(
widget.account, file_util.unstripPath(widget.account, r)));
}
} catch (e, stackTrace) {