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