mirror of
https://github.com/lifegpc/eh_downloader_flutter.git
synced 2026-06-10 15:59:25 +08:00
Add mutex to putCache
This commit is contained in:
@@ -4,6 +4,7 @@ import 'dart:typed_data';
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/local.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:mutex/mutex.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
@@ -33,6 +34,7 @@ class ImageCaches {
|
||||
static const version = 1;
|
||||
int _size = 0;
|
||||
int get size => _size;
|
||||
late Mutex _mutex;
|
||||
ImageCaches();
|
||||
Future<String?> _desktopFilePath() async {
|
||||
final String? exe = await platformPath.getCurrentExe();
|
||||
@@ -166,6 +168,7 @@ class ImageCaches {
|
||||
await _createDir();
|
||||
if (!(await _checkDatabase())) await _createTable();
|
||||
await _updateSize();
|
||||
_mutex = Mutex();
|
||||
_inited = true;
|
||||
}
|
||||
|
||||
@@ -201,39 +204,42 @@ class ImageCaches {
|
||||
Future<void> putCache(String uri, Uint8List data,
|
||||
Map<String, List<String>> headers, String? realUri) async {
|
||||
if (!_inited) return;
|
||||
final u = Uri.parse(uri);
|
||||
final dir = await cacheDir;
|
||||
String p = path.join(dir.path, u.host.isEmpty ? "nohost" : u.host,
|
||||
u.path.substring(1) + (u.hasQuery ? "?${u.query}" : ""));
|
||||
final d = _fs.directory(path.dirname(p));
|
||||
if (isWindows) {
|
||||
if (path.isAbsolute(p)) {
|
||||
p = p.substring(0, 2) +
|
||||
p.substring(2).replaceAll(RegExp("[:\\*\\?\"\\<\\>\\|]"), '_');
|
||||
} else {
|
||||
p = p.replaceAll(RegExp("[:\\*\\?\"\\<\\>\\|]"), '_');
|
||||
await _mutex.protect(() async {
|
||||
final u = Uri.parse(uri);
|
||||
final dir = await cacheDir;
|
||||
String p = path.join(dir.path, u.host.isEmpty ? "nohost" : u.host,
|
||||
u.path.substring(1) + (u.hasQuery ? "?${u.query}" : ""));
|
||||
final d = _fs.directory(path.dirname(p));
|
||||
if (isWindows) {
|
||||
if (path.isAbsolute(p)) {
|
||||
p = p.substring(0, 2) +
|
||||
p.substring(2).replaceAll(RegExp("[:\\*\\?\"\\<\\>\\|]"), '_');
|
||||
} else {
|
||||
p = p.replaceAll(RegExp("[:\\*\\?\"\\<\\>\\|]"), '_');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(await d.exists())) {
|
||||
await d.create(recursive: true);
|
||||
}
|
||||
final f = _fs.file(p);
|
||||
await f.writeAsBytes(data.toList());
|
||||
final lastUsed = DateTime.now().millisecondsSinceEpoch;
|
||||
final header = jsonEncode(headers);
|
||||
if (_exeDir != null) {
|
||||
p = path.relative(p, from: _exeDir!);
|
||||
}
|
||||
final exes = await _db!.query("images", where: 'url = ?', whereArgs: [uri]);
|
||||
await _db!.rawInsert(
|
||||
"INSERT OR REPLACE INTO images VALUES (?, ?, ?, ?, ?, ?);",
|
||||
[uri, p, lastUsed, header, realUri, data.length]);
|
||||
if (exes.isEmpty) {
|
||||
_size += data.length;
|
||||
} else {
|
||||
final originalSize = (exes[0]["size"] as int?) ?? 0;
|
||||
_size += (data.length - originalSize);
|
||||
}
|
||||
if (!(await d.exists())) {
|
||||
await d.create(recursive: true);
|
||||
}
|
||||
final f = _fs.file(p);
|
||||
await f.writeAsBytes(data.toList());
|
||||
final lastUsed = DateTime.now().millisecondsSinceEpoch;
|
||||
final header = jsonEncode(headers);
|
||||
if (_exeDir != null) {
|
||||
p = path.relative(p, from: _exeDir!);
|
||||
}
|
||||
final exes =
|
||||
await _db!.query("images", where: 'url = ?', whereArgs: [uri]);
|
||||
await _db!.rawInsert(
|
||||
"INSERT OR REPLACE INTO images VALUES (?, ?, ?, ?, ?, ?);",
|
||||
[uri, p, lastUsed, header, realUri, data.length]);
|
||||
if (exes.isEmpty) {
|
||||
_size += data.length;
|
||||
} else {
|
||||
final originalSize = (exes[0]["size"] as int?) ?? 0;
|
||||
_size += (data.length - originalSize);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> updateSize({bool clear = false}) async {
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:js_interop';
|
||||
import 'dart:js_interop_unsafe';
|
||||
import 'dart:typed_data';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:mutex/mutex.dart';
|
||||
import 'package:web/web.dart';
|
||||
import 'web/indexed_db.dart';
|
||||
|
||||
@@ -14,6 +15,7 @@ class ImageCaches {
|
||||
int get size => _size;
|
||||
late IndexedDb _db;
|
||||
bool _inited = false;
|
||||
late Mutex _mutex;
|
||||
Future<void> _updateSize() async {
|
||||
int total = 0;
|
||||
await _db.openCursor("images", (cur) {
|
||||
@@ -51,6 +53,7 @@ class ImageCaches {
|
||||
}, 1);
|
||||
await _db.init();
|
||||
await _updateSize();
|
||||
_mutex = Mutex();
|
||||
_inited = true;
|
||||
}
|
||||
|
||||
@@ -90,27 +93,29 @@ class ImageCaches {
|
||||
Future<void> putCache(String uri, Uint8List data,
|
||||
Map<String, List<String>> headers, String? realUri) async {
|
||||
if (!_inited) return;
|
||||
final he = JSObject();
|
||||
for (final e in headers.entries) {
|
||||
he.setProperty(e.key.toJS, e.value.map((e) => e.toJS).toList().toJS);
|
||||
}
|
||||
final opts = ResponseInit(status: 200, statusText: 'OK', headers: he);
|
||||
final lastUsed = DateTime.now().millisecondsSinceEpoch;
|
||||
final res = Response(data.toJS, opts);
|
||||
await cache.put(uri.toJS, res).toDart;
|
||||
final oObj = (await _db.get("images", uri.toJS)) as JSObject?;
|
||||
final obj = JSObject();
|
||||
obj.setProperty("url".toJS, uri.toJS);
|
||||
obj.setProperty("size".toJS, data.length.toJS);
|
||||
obj.setProperty("last_used".toJS, lastUsed.toJS);
|
||||
await _db.put("images", obj);
|
||||
if (oObj == null) {
|
||||
_size += data.length;
|
||||
} else {
|
||||
final originalSize =
|
||||
(oObj!.getProperty("size".toJS) as JSNumber).toDartInt;
|
||||
_size += (data.length - originalSize);
|
||||
}
|
||||
await _mutex.protect(() async {
|
||||
final he = JSObject();
|
||||
for (final e in headers.entries) {
|
||||
he.setProperty(e.key.toJS, e.value.map((e) => e.toJS).toList().toJS);
|
||||
}
|
||||
final opts = ResponseInit(status: 200, statusText: 'OK', headers: he);
|
||||
final lastUsed = DateTime.now().millisecondsSinceEpoch;
|
||||
final res = Response(data.toJS, opts);
|
||||
await cache.put(uri.toJS, res).toDart;
|
||||
final oObj = (await _db.get("images", uri.toJS)) as JSObject?;
|
||||
final obj = JSObject();
|
||||
obj.setProperty("url".toJS, uri.toJS);
|
||||
obj.setProperty("size".toJS, data.length.toJS);
|
||||
obj.setProperty("last_used".toJS, lastUsed.toJS);
|
||||
await _db.put("images", obj);
|
||||
if (oObj == null) {
|
||||
_size += data.length;
|
||||
} else {
|
||||
final originalSize =
|
||||
(oObj!.getProperty("size".toJS) as JSNumber).toDartInt;
|
||||
_size += (data.length - originalSize);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> updateSize({bool clear = false}) async {
|
||||
|
||||
@@ -558,6 +558,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
mutex:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mutex
|
||||
sha256: "8827da25de792088eb33e572115a5eb0d61d61a3c01acbc8bcbe76ed78f1a1f2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -29,6 +29,7 @@ dependencies:
|
||||
json_annotation: ^4.9.0
|
||||
keymap: ^0.0.92
|
||||
logging: ^1.2.0
|
||||
mutex: ^3.1.0
|
||||
package_info_plus: ^8.0.0
|
||||
palette_generator: ^0.3.3+3
|
||||
path: ^1.8.3
|
||||
|
||||
Reference in New Issue
Block a user