toc.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { Worker } from 'worker_threads';
  2. import cliProgress from 'cli-progress';
  3. const MAX_THREADS = 10;
  4. export async function saveToc(epub, uploadPath, book_id, author_id) {
  5. const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
  6. progressBar.start(epub.toc.length, 0);
  7. let activeWorkers = 0;
  8. let currentIndex = 0;
  9. const promises = [];
  10. function startNextWorker() {
  11. if (currentIndex >= epub.toc.length) {
  12. return;
  13. }
  14. const elm = epub.toc[currentIndex];
  15. currentIndex++;
  16. activeWorkers++;
  17. const promise = new Promise((resolve, reject) => {
  18. const worker = new Worker(new URL('./worker.mjs', import.meta.url), {
  19. workerData: { elm, book_id, author_id }
  20. });
  21. worker.on('message', (message) => {
  22. progressBar.increment();
  23. activeWorkers--;
  24. resolve(message);
  25. startNextWorker();
  26. });
  27. worker.on('error', (err) => {
  28. activeWorkers--;
  29. reject(err);
  30. startNextWorker();
  31. });
  32. worker.on('exit', (code) => {
  33. if (code !== 0) {
  34. reject(new Error(`Worker stopped with exit code ${code}`));
  35. }
  36. });
  37. });
  38. promises.push(promise);
  39. }
  40. for (let i = 0; i < Math.min(MAX_THREADS, epub.toc.length); i++) {
  41. startNextWorker();
  42. }
  43. await Promise.all(promises);
  44. progressBar.stop();
  45. }