mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 06:46:22 +01:00
Only cache a dir after its children are synced and cached
This commit is contained in:
parent
d5d69144de
commit
a3d3c6c375
2 changed files with 77 additions and 16 deletions
|
@ -568,6 +568,22 @@ class FileSqliteDbDataSource implements FileDataSource {
|
|||
static final _log = Logger("entity.file.data_source.FileSqliteDbDataSource");
|
||||
}
|
||||
|
||||
class IntermediateSyncState {
|
||||
const IntermediateSyncState({
|
||||
required this.account,
|
||||
required this.dir,
|
||||
required this.remoteTouchEtag,
|
||||
required this.files,
|
||||
required this.shouldCache,
|
||||
});
|
||||
|
||||
final Account account;
|
||||
final File dir;
|
||||
final String? remoteTouchEtag;
|
||||
final List<File> files;
|
||||
final bool shouldCache;
|
||||
}
|
||||
|
||||
class FileCachedDataSource implements FileDataSource {
|
||||
FileCachedDataSource(
|
||||
this._c, {
|
||||
|
@ -598,21 +614,29 @@ class FileCachedDataSource implements FileDataSource {
|
|||
Account account,
|
||||
File dir, {
|
||||
required String? remoteTouchEtag,
|
||||
}) async {
|
||||
final state = await beginSync(
|
||||
account,
|
||||
dir,
|
||||
remoteTouchEtag: remoteTouchEtag,
|
||||
);
|
||||
return concludeSync(state);
|
||||
}
|
||||
|
||||
Future<IntermediateSyncState> beginSync(
|
||||
Account account,
|
||||
File dir, {
|
||||
required String? remoteTouchEtag,
|
||||
}) async {
|
||||
try {
|
||||
final remote = await _remoteSrc.list(account, dir);
|
||||
await FileSqliteCacheUpdater(_c)(account, dir, remote: remote);
|
||||
if (shouldCheckCache) {
|
||||
// update our local touch token to match the remote one
|
||||
try {
|
||||
_log.info("[list] Update outdated local etag: ${dir.path}");
|
||||
await _c.touchManager.setLocalEtag(account, dir, remoteTouchEtag);
|
||||
} catch (e, stacktrace) {
|
||||
_log.shout("[list] Failed while setLocalToken", e, stacktrace);
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
return remote;
|
||||
return IntermediateSyncState(
|
||||
account: account,
|
||||
dir: dir,
|
||||
remoteTouchEtag: remoteTouchEtag,
|
||||
files: remote,
|
||||
shouldCache: true,
|
||||
);
|
||||
} on ApiException catch (e) {
|
||||
if (e.response.statusCode == 404) {
|
||||
_log.info("[list] File removed: $dir");
|
||||
|
@ -622,7 +646,13 @@ class FileCachedDataSource implements FileDataSource {
|
|||
_log.warning(
|
||||
"[list] Failed while remove from db, file not cached?", e);
|
||||
}
|
||||
return [];
|
||||
return IntermediateSyncState(
|
||||
account: account,
|
||||
dir: dir,
|
||||
remoteTouchEtag: remoteTouchEtag,
|
||||
files: [],
|
||||
shouldCache: false,
|
||||
);
|
||||
} else if (e.response.statusCode == 403) {
|
||||
_log.info("[list] E2E encrypted dir: $dir");
|
||||
try {
|
||||
|
@ -633,13 +663,40 @@ class FileCachedDataSource implements FileDataSource {
|
|||
_log.warning(
|
||||
"[list] Failed while emptying from db, file not cached?", e);
|
||||
}
|
||||
return [];
|
||||
return IntermediateSyncState(
|
||||
account: account,
|
||||
dir: dir,
|
||||
remoteTouchEtag: remoteTouchEtag,
|
||||
files: [],
|
||||
shouldCache: false,
|
||||
);
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<File>> concludeSync(IntermediateSyncState state) async {
|
||||
if (!state.shouldCache) {
|
||||
return state.files;
|
||||
}
|
||||
|
||||
await FileSqliteCacheUpdater(_c)(state.account, state.dir,
|
||||
remote: state.files);
|
||||
if (shouldCheckCache) {
|
||||
// update our local touch token to match the remote one
|
||||
try {
|
||||
_log.info("[list] Update outdated local etag: ${state.dir.path}");
|
||||
await _c.touchManager
|
||||
.setLocalEtag(state.account, state.dir, state.remoteTouchEtag);
|
||||
} catch (e, stacktrace) {
|
||||
_log.shout("[list] Failed while setLocalToken", e, stacktrace);
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
return state.files;
|
||||
}
|
||||
|
||||
@override
|
||||
listSingle(Account account, File f) async {
|
||||
final remote = await _remoteSrc.listSingle(account, f);
|
||||
|
|
|
@ -56,9 +56,12 @@ class SyncDir {
|
|||
}
|
||||
_log.info("[_syncDir] Dir changed: ${remoteDir.path}");
|
||||
|
||||
final children = await FileCachedDataSource(_c, shouldCheckCache: true)
|
||||
.sync(account, remoteDir, remoteTouchEtag: status.item2);
|
||||
final dataSrc = FileCachedDataSource(_c, shouldCheckCache: true);
|
||||
final syncState = await dataSrc.beginSync(account, remoteDir,
|
||||
remoteTouchEtag: status.item2);
|
||||
final children = syncState.files;
|
||||
if (!isRecursive) {
|
||||
await dataSrc.concludeSync(syncState);
|
||||
return true;
|
||||
}
|
||||
final subDirs = children
|
||||
|
@ -88,6 +91,7 @@ class SyncDir {
|
|||
}
|
||||
progress.next();
|
||||
}
|
||||
await dataSrc.concludeSync(syncState);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue