mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-08 18:28:53 +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");
|
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 {
|
class FileCachedDataSource implements FileDataSource {
|
||||||
FileCachedDataSource(
|
FileCachedDataSource(
|
||||||
this._c, {
|
this._c, {
|
||||||
|
@ -598,21 +614,29 @@ class FileCachedDataSource implements FileDataSource {
|
||||||
Account account,
|
Account account,
|
||||||
File dir, {
|
File dir, {
|
||||||
required String? remoteTouchEtag,
|
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 {
|
}) async {
|
||||||
try {
|
try {
|
||||||
final remote = await _remoteSrc.list(account, dir);
|
final remote = await _remoteSrc.list(account, dir);
|
||||||
await FileSqliteCacheUpdater(_c)(account, dir, remote: remote);
|
return IntermediateSyncState(
|
||||||
if (shouldCheckCache) {
|
account: account,
|
||||||
// update our local touch token to match the remote one
|
dir: dir,
|
||||||
try {
|
remoteTouchEtag: remoteTouchEtag,
|
||||||
_log.info("[list] Update outdated local etag: ${dir.path}");
|
files: remote,
|
||||||
await _c.touchManager.setLocalEtag(account, dir, remoteTouchEtag);
|
shouldCache: true,
|
||||||
} catch (e, stacktrace) {
|
);
|
||||||
_log.shout("[list] Failed while setLocalToken", e, stacktrace);
|
|
||||||
// ignore error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return remote;
|
|
||||||
} on ApiException catch (e) {
|
} on ApiException catch (e) {
|
||||||
if (e.response.statusCode == 404) {
|
if (e.response.statusCode == 404) {
|
||||||
_log.info("[list] File removed: $dir");
|
_log.info("[list] File removed: $dir");
|
||||||
|
@ -622,7 +646,13 @@ class FileCachedDataSource implements FileDataSource {
|
||||||
_log.warning(
|
_log.warning(
|
||||||
"[list] Failed while remove from db, file not cached?", e);
|
"[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) {
|
} else if (e.response.statusCode == 403) {
|
||||||
_log.info("[list] E2E encrypted dir: $dir");
|
_log.info("[list] E2E encrypted dir: $dir");
|
||||||
try {
|
try {
|
||||||
|
@ -633,13 +663,40 @@ class FileCachedDataSource implements FileDataSource {
|
||||||
_log.warning(
|
_log.warning(
|
||||||
"[list] Failed while emptying from db, file not cached?", e);
|
"[list] Failed while emptying from db, file not cached?", e);
|
||||||
}
|
}
|
||||||
return [];
|
return IntermediateSyncState(
|
||||||
|
account: account,
|
||||||
|
dir: dir,
|
||||||
|
remoteTouchEtag: remoteTouchEtag,
|
||||||
|
files: [],
|
||||||
|
shouldCache: false,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
rethrow;
|
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
|
@override
|
||||||
listSingle(Account account, File f) async {
|
listSingle(Account account, File f) async {
|
||||||
final remote = await _remoteSrc.listSingle(account, f);
|
final remote = await _remoteSrc.listSingle(account, f);
|
||||||
|
|
|
@ -56,9 +56,12 @@ class SyncDir {
|
||||||
}
|
}
|
||||||
_log.info("[_syncDir] Dir changed: ${remoteDir.path}");
|
_log.info("[_syncDir] Dir changed: ${remoteDir.path}");
|
||||||
|
|
||||||
final children = await FileCachedDataSource(_c, shouldCheckCache: true)
|
final dataSrc = FileCachedDataSource(_c, shouldCheckCache: true);
|
||||||
.sync(account, remoteDir, remoteTouchEtag: status.item2);
|
final syncState = await dataSrc.beginSync(account, remoteDir,
|
||||||
|
remoteTouchEtag: status.item2);
|
||||||
|
final children = syncState.files;
|
||||||
if (!isRecursive) {
|
if (!isRecursive) {
|
||||||
|
await dataSrc.concludeSync(syncState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final subDirs = children
|
final subDirs = children
|
||||||
|
@ -88,6 +91,7 @@ class SyncDir {
|
||||||
}
|
}
|
||||||
progress.next();
|
progress.next();
|
||||||
}
|
}
|
||||||
|
await dataSrc.concludeSync(syncState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue