fix: mark sftp mission as completed when dispose

This commit is contained in:
lollipopkit
2023-09-12 13:26:14 +08:00
parent 730a62831b
commit 700322c603
8 changed files with 56 additions and 37 deletions

View File

@@ -58,13 +58,18 @@ class SftpReqStatus {
@override
int get hashCode => id ^ super.hashCode;
void dispose() {
// ignore: deprecated_member_use_from_same_package
worker.dispose();
completer?.complete();
}
void onNotify(dynamic event) {
switch (event.runtimeType) {
case SftpWorkerStatus:
status = event;
if (status == SftpWorkerStatus.finished) {
worker.dispose();
completer?.complete();
dispose();
}
break;
case double:

View File

@@ -20,6 +20,13 @@ class SftpWorker {
required this.req,
});
/// Use [@Deprecated] to prevent calling [SftpWorker.dispose] directly
///
/// Don't delete this method
@Deprecated(
"Use [SftpWorkerStatus.dispose] to dispose the worker, "
"instead of [SftpWorker.dispose]",
)
void dispose() {
worker.dispose();
}
@@ -77,24 +84,27 @@ Future<void> _download(
final client = await genClient(req.spi, privateKey: req.privateKey);
mainSendPort.send(SftpWorkerStatus.sshConnectted);
await Directory(req.localPath.substring(0, req.localPath.lastIndexOf('/')))
.create(recursive: true);
final local = File(req.localPath);
if (await local.exists()) {
await local.delete();
}
final localFile = local.openWrite(mode: FileMode.append);
/// Create the directory if not exists
final dirPath = req.localPath.substring(0, req.localPath.lastIndexOf('/'));
await Directory(dirPath).create(recursive: true);
/// Use [FileMode.write] to overwrite the file
final localFile = File(req.localPath).openWrite(mode: FileMode.write);
final file = await (await client.sftp()).open(req.remotePath);
final size = (await file.stat()).size;
if (size == null) {
mainSendPort.send(Exception('can not get file size'));
mainSendPort.send(Exception('can\'t get file size: ${req.remotePath}'));
return;
}
// Read 10m each time
const defaultChunkSize = 1024 * 1024 * 10;
final chunkSize = size > defaultChunkSize ? defaultChunkSize : size;
mainSendPort.send(size);
mainSendPort.send(SftpWorkerStatus.loading);
// Read 2m each time
// Issue #161
// The download speed is about 2m/s may due to single core performance
const defaultChunkSize = 1024 * 1024 * 2;
final chunkSize = size > defaultChunkSize ? defaultChunkSize : size;
for (var i = 0; i < size; i += chunkSize) {
final fileData = file.read(length: chunkSize);
await for (var form in fileData) {
@@ -102,8 +112,10 @@ Future<void> _download(
mainSendPort.send((i + form.length) / size * 100);
}
}
await localFile.close();
await file.close();
mainSendPort.send(watch.elapsed);
mainSendPort.send(SftpWorkerStatus.finished);
} catch (e) {