Skip to content

Clear cache filesystem when emptying the store cache #477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions flutter_cache_manager/lib/src/cache_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,19 @@ class CacheStore {

Future<void> emptyCache() async {
final provider = await _cacheInfoRepository;
final toRemove = <int>[];
final allObjects = await provider.getAllObjects();
var futures = <Future>[];

// Remove the cache files from the filesystem
await _removeCacheDir();

// Delete objects from store
final toRemove = <int>{};
for (final cacheObject in allObjects) {
futures.add(_removeCachedFile(cacheObject, toRemove));
if (cacheObject.id != null) {
toRemove.add(cacheObject.id!);
}
}
await Future.wait(futures);

await provider.deleteAll(toRemove);
}

Expand Down Expand Up @@ -195,6 +201,18 @@ class CacheStore {
}
}

Future<void> _removeCacheDir() async {
_memCache.clear();
_futureCache.clear();

try {
await fileSystem.deleteCacheDir();
} on FileSystemException {
// If the filesystem implementation doesn't check if the file
// exists before deleting it could fail
}
}

bool memoryCacheContainsKey(String key) {
return _memCache.containsKey(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export 'file_system_web.dart';

import 'package:file/file.dart';

/// FileSystem works in the context of a directory where filenames are stored.
abstract class FileSystem {
Future<File> createFile(String name);

/// Deletes the directory that contains all the cached filed in the current context.
Future<void> deleteCacheDir();
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,13 @@ class IOFileSystem implements FileSystem {
}
return directory.childFile(name);
}

@override
Future<void> deleteCacheDir() async {
final directory = await _fileDir;

if (await directory.exists()) {
await directory.delete(recursive: true);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import 'package:file/file.dart' show File;
import 'package:file/file.dart' show File, Directory;
import 'package:file/memory.dart';
import 'package:flutter_cache_manager/src/storage/file_system/file_system.dart';

class MemoryCacheSystem implements FileSystem {
final directory = MemoryFileSystem().systemTempDirectory.createTemp('cache');
Future<Directory> _fileDir;

MemoryCacheSystem() : _fileDir = _createTempDirectory();

@override
Future<File> createFile(String name) async {
return (await directory).childFile(name);
Directory directory = await _fileDir;
if (!(await directory.exists())) {
// Because _createTempDirectory assigns a new name we need to reassing the future
_fileDir = _createTempDirectory();
directory = await _fileDir;
}

return directory.childFile(name);
}

static Future<Directory> _createTempDirectory() async {
return MemoryFileSystem().systemTempDirectory.createTemp('cache');
}

@override
Future<void> deleteCacheDir() async {
final dir = await _fileDir;
if (await dir.exists()) {
await dir.delete(recursive: true);
}
}
}
22 changes: 20 additions & 2 deletions flutter_cache_manager/test/cache_store_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ void main() {
var config = createTestConfig();
var store = CacheStore(config);
store.cleanupRunMinInterval = const Duration(milliseconds: 1);
await config.returnsFile('testimage.png');

var co1 = CacheObject(
'baseflow.com/test.png',
Expand All @@ -394,11 +393,30 @@ void main() {
validTill: clock.now().add(const Duration(days: 7)),
);

final cacheObjects = [co1, co2, co3];

// Write the cache files to the filesystem
final List<File> cacheFiles = [];
for (var cacheObject in cacheObjects) {
final f = await config.returnsFile(cacheObject.relativePath);
cacheFiles.add(f);
}

// Include an extra file
// This could be a desync between the store and the filesystem
cacheFiles
.add(await config.returnsFile("non-existent-file-in-store.png"));

when(config.mockRepo.getAllObjects())
.thenAnswer((_) => Future.value([co1, co2, co3]));
.thenAnswer((_) => Future.value(cacheObjects));

await store.emptyCache();

// make sure that all cached files in the filesystem are deleted
for (var cacheFile in cacheFiles) {
expect(await cacheFile.exists(), isFalse);
}

verify(config.mockRepo
.deleteAll(argThat(containsAll([co1.id, co2.id, co3.id])))).called(1);
});
Expand Down
8 changes: 8 additions & 0 deletions flutter_cache_manager/test/helpers/test_configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@ class TestFileSystem extends FileSystem {
await dir.create(recursive: true);
return dir.childFile(name);
}

@override
Future<void> deleteCacheDir() async {
var dir = await directoryFuture;
if (await dir.exists()) {
await dir.delete(recursive: true);
}
}
}