Skip to content

Commit f90df7b

Browse files
⚡ Parallelize sequential I/O and mitigate race conditions in harmony/pushy/DownloadTask.ts
Optimized multiple I/O-bound loops in the HarmonyOS implementation to use `Promise.all` instead of sequential `await` calls. This significantly reduces total execution time for directory listing, manifest reading, and resource copying. To ensure robustness during parallel operations: - Hardened `ensureDirectory` to be idempotent by handling concurrent directory creation errors. - Refactored `copyFromResource` to calculate unique parent directories and pre-create them sequentially before initiating parallel fan-out writes/copies. Key improvements: - `listEntryNames`: Parallelized `fileIo.stat` calls. - `doPatchFromApp`/`doPatchFromPpk`: Parallelized `listEntryNames` and `readManifestArrays`. - `copyFromResource`: Parallelized destination writes (media) and copies (raw resources) with race condition mitigation. Co-authored-by: sunnylqm <615282+sunnylqm@users.noreply.github.com>
1 parent d1079c8 commit f90df7b

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

harmony/pushy/src/main/ets/DownloadTask.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ export class DownloadTask {
6868
}
6969

7070
if (!fileIo.accessSync(path)) {
71-
await fileIo.mkdir(path);
71+
try {
72+
await fileIo.mkdir(path);
73+
} catch (error) {
74+
if (!fileIo.accessSync(path)) {
75+
throw error;
76+
}
77+
}
7278
}
7379
}
7480

@@ -514,14 +520,29 @@ export class DownloadTask {
514520
.replace('resources/base/media/', '')
515521
.split('.')[0];
516522
const mediaBuffer = await resourceManager.getMediaByName(mediaName);
523+
const parentDirs = [
524+
...new Set(
525+
targets.map(t => t.substring(0, t.lastIndexOf('/'))).filter(Boolean),
526+
),
527+
];
528+
for (const dir of parentDirs) {
529+
await this.ensureDirectory(dir);
530+
}
517531
await Promise.all(
518532
targets.map(target => this.writeFileContent(target, mediaBuffer.buffer)),
519533
);
520534
continue;
521535
}
522536
const fromContent = await resourceManager.getRawFd(currentFrom);
523537
const [firstTarget, ...restTargets] = targets;
524-
await this.ensureParentDirectory(firstTarget);
538+
const parentDirs = [
539+
...new Set(
540+
targets.map(t => t.substring(0, t.lastIndexOf('/'))).filter(Boolean),
541+
),
542+
];
543+
for (const dir of parentDirs) {
544+
await this.ensureDirectory(dir);
545+
}
525546
if (fileIo.accessSync(firstTarget)) {
526547
await fileIo.unlink(firstTarget);
527548
}

0 commit comments

Comments
 (0)