multi-tasks 3.5.0 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@ Run large batches of tasks in parallel across multiple Node.js processes, with z
4
4
 
5
5
  **New in 3.5.0 — `task_storage: 'memory'`**: keep all task state in the master process's memory instead of on disk. Same API, one config field — and ~17× faster on huge batches of small tasks. The trade-off: no resume. See [Task storage modes](#task-storage-modes).
6
6
 
7
- ![task_storage benchmark: file mode 195.1s vs memory mode 11.2s — 17.4x faster](bench-storage.svg)
7
+ ![task_storage benchmark: file mode 195.1s vs memory mode 11.2s — 17.4x faster](https://cdn.jsdelivr.net/npm/multi-tasks@latest/bench-storage.svg)
8
8
 
9
9
  ### Install:
10
10
 
@@ -170,34 +170,26 @@ multiTasks({
170
170
  taskRootFolder: './my-tasks',
171
171
  taskId: 'demo',
172
172
  task_storage: 'memory', //'file' (default) | 'memory'
173
+ onFinish: (report, helper) => {
174
+ helper.foreachResult((count, task, result, succeeded) => {
175
+ //collect / batch-insert / write out your results here
176
+ });
177
+ },
173
178
  });
174
179
  ```
175
180
 
176
181
  - **`file`** (default) — every state change hits disk immediately; resume anytime.
177
- - **`memory`** — task states, results, logs and user messages live in the master process's memory only; no per-task files are ever written. The task folder is still created with the usual subfolders (`progress`/`results`/`logs` stay empty), holding only `task_config.json` and `.sys/run.log`. Dramatically faster for large batches of small tasks about 20x faster in benchmarks. Results are still available through `onFinish(report, helper)`. `resume`/`retry_fails`/`restart` are not supported for this mode and throw when called — a killed run is simply gone.
178
-
179
- Benchmark — 30,000 tiny tasks × 28 workers, average of 3 runs on the same machine (17–27× across repeated benchmark sessions):
180
-
181
- ![task_storage benchmark: file mode 195.1s vs memory mode 11.2s — 17.4x faster](bench-storage.svg)
182
+ - **`memory`** — task states, results and logs stay in the master's memory; nothing per-task is written to disk, so `onFinish(report, helper)` is the only exit for your results collect them with `helper.foreachResult` (or `foreachSuccResult`/`foreachErrorResult`) as above; if you need per-task files, write them in bulk there. `resume`/`retry_fails`/`restart` throw — a killed run is simply gone.
182
183
 
183
- **Getting results out in `memory` mode**: since nothing per-task hits disk, `onFinish(report, helper)` is the one and only exit for your data — iterate everything with `helper.foreachResult` (or `foreachSuccResult`/`foreachErrorResult`) and persist it yourself in one batch if you need it kept:
184
-
185
- ```javascript
186
- onFinish: (report, helper) => {
187
- helper.foreachResult((count, task, result, succeeded) => {
188
- //collect / batch-insert / write out — all results are here in memory
189
- });
190
- },
191
- ```
184
+ Benchmark 30,000 tiny tasks × 28 workers:
192
185
 
193
- If you need per-task files anyway, write them in bulk from `onFinish` do **not** `writeFileSync` inside `processTask`: in benchmarks (30,000 tasks × 28 workers) per-task self-written files made the run ~3. slower than pure `memory` (27.7s vs 8.4s), because disk writes still dominate even without the library's bookkeeping. (That said, even the slow do-it-yourself variant beats `file` mode's ~195s — its cost is the resumable state machine, not the writes alone.)
186
+ ![task_storage benchmark: file mode 195.1s vs memory mode 11.2s17.4x faster](https://cdn.jsdelivr.net/npm/multi-tasks@latest/bench-storage.svg)
194
187
 
195
188
  Caveats of `memory` mode:
196
189
 
197
- - **Monitoring**: [multi-tasks-monitor](#real-time-monitoring) reads the task folder, so it has nothing to show for a `memory` run (no task states/results on disk).
198
- - **Worker crashes**: without `maxTaskRetries`, a crashed worker's in-flight task is not retried with `file` it stays in `running` until a later `resume` picks it up; with `memory` it is lost for good.
199
- - **Dynamic tasks**: with `memory`, `helper.createNewTasks` reaches the master over IPC; if the master is killed before applying them, tasks created but not yet applied are lost. (`file` mode writes them to disk from the worker directly.)
200
- - **Dynamic tasks with `autoCloseAfterCompletion`**: in `memory` mode the master pops straight from the in-memory queue — there is no on-disk re-read fallback like in `file` mode, and no settle delay before killing an idle worker. A task another worker just sent via `helper.createNewTasks` may still be in IPC transit when the master decides the queue is empty, so it can miss the dispatch window and the workers get closed. If your workers create tasks dynamically, keep `autoCloseAfterCompletion` at its default `false`.
190
+ - **Monitoring**: [multi-tasks-monitor](#real-time-monitoring) reads the task folder, so it has nothing to show for a `memory` run.
191
+ - **Worker crashes**: without `maxTaskRetries`, a crashed worker's in-flight task is lost for good (no `resume` to pick it up).
192
+ - **Dynamic tasks**: tasks sent via `helper.createNewTasks` but not yet applied are lost if the master is killed. And keep `autoCloseAfterCompletion` at its default `false` when workers create tasks dynamically in-transit tasks can miss the dispatch window and the workers get closed early.
201
193
 
202
194
  ### Broadcasting events between workers:
203
195
 
@@ -297,6 +289,8 @@ npx multi-tasks-monitor --task-dir "D:\tasks\multitasks20260806..." --port 3777
297
289
 
298
290
  ### Changelog:
299
291
 
292
+ - 3.5.2 Fix Readme
293
+ - 3.5.1 Fix bench-storage.svg
300
294
  - 3.5.0 Add `task_storage: 'memory'` mode (~17x faster, no resume)
301
295
  - 3.4.1 Rewrite README: simpler structure, all examples verified by test cases
302
296
  - 3.4.0 Show per-worker load (ELU/CPU/memory) under progressBar; stability fixes
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="720" height="252" viewBox="0 0 720 252" font-family="Segoe UI, Helvetica, Arial, sans-serif">
2
+ <rect x="1" y="1" width="718" height="250" rx="8" fill="#ffffff" stroke="#dadce0"/>
3
+ <text x="24" y="38" font-size="17" font-weight="600" fill="#202124">task_storage benchmark — 30,000 tasks × 28 workers</text>
4
+ <text x="24" y="60" font-size="12" fill="#5f6368">wall-clock time of a full run, average of 3 runs · lower is better</text>
5
+
6
+ <text x="112" y="114" font-size="14" fill="#202124" text-anchor="end">file</text>
7
+ <rect x="120" y="94" width="420" height="34" rx="3" fill="#9aa0a6"/>
8
+ <text x="548" y="116" font-size="14" fill="#202124">195.1s · 154 tasks/s</text>
9
+
10
+ <text x="112" y="172" font-size="14" fill="#202124" text-anchor="end">memory</text>
11
+ <rect x="120" y="152" width="24" height="34" rx="3" fill="#188038"/>
12
+ <text x="152" y="174" font-size="14" fill="#202124">11.2s · 2,676 tasks/s</text>
13
+ <text x="360" y="174" font-size="15" font-weight="700" fill="#188038">17.4× faster</text>
14
+
15
+ <line x1="120" y1="208" x2="540" y2="208" stroke="#e8eaed"/>
16
+ <text x="24" y="232" font-size="11" fill="#5f6368">per-round walls — file: 202.7 / 193.6 / 188.9s · memory: 11.3 / 11.1 / 11.3s · Windows 11, SSD · script: test-manual/bench-storage.js</text>
17
+ </svg>
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "multi-tasks",
3
- "version": "3.5.0",
3
+ "version": "3.5.2",
4
4
  "description": "Multi-process task scheduling based on Node.js cluster, with crash resume and failed-task restart support",
5
5
  "main": "index.js",
6
6
  "files": [
7
7
  "index.js",
8
8
  "workers",
9
- "utils/*.js"
9
+ "utils/*.js",
10
+ "bench-storage.svg"
10
11
  ],
11
12
  "repository": {
12
13
  "type": "git",