0

I have a route named pdf and if I go to the route it waits 10 sec because I create a pdf and other things. But if I go to other screen and the pdf route is not finish yet then my other response waiting and I can not use the site until pdf route is finish. How can I not block the response ?

PDFCreate file

var pdf = require("pdf-creator-node");
const path = require('path');
import fs from 'fs-extra';

export default async function PDFCreate() {
  try {
    var options = {
      format: "A3",
      orientation: "portrait",
      border: "10mm",
      header: {
          height: "0mm",
      },
      footer: {
          height: "28mm",
          contents: {
              first: 'Cover page',
              2: 'Second page', // Any page number is working. 1-based index
              default: '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
              last: 'Last Page'
          }
      }
  };
    console.log(path.join(__dirname));
    const html = fs.readFileSync('app/data/file.html', 'utf-8');
    const bitmap = fs.readFileSync('public/images/lg.jpeg');
    const logo = bitmap.toString('base64');
    const filename = Math.random() + '_doc' + '.pdf';

    const document = {
      html: html,
      data: {
        logo
      },
      path: './docs/' + filename
  }

    pdf.create(document, options)
    .then(res => {
        console.log(res);
    }).catch(error => {
        console.log(error);
    });

    const filepath = 'http://localhost:3000/public/images/' + filename;

    return filepath;
  } catch(e) {
    console.log(e);
    throw e;
  }
}

/PDF route (I use fullstack framework so the loader is equivalent with this: route.get('/s', (res, req)'))

import PDFCreate from '~/data/createPDF.server'

export default async function loader() {
  try {
    await PDFCreate();
    return null;
  } catch(e) {
    console.log(e);
  }
}

/home

export default function Home() {
  return (
    <>
      <main className="container test">
        <p>test</p>
      </main>
    </>
  )
};

So when I call /pdf and its loading and if I go to home route then my home route loads until /pdf is finish... how can I not block this?

reacter777
  • 67
  • 4

2 Answers2

0

You have part of the code with await PDFCreate();, which makes your whole code stop and wait for PDFCreate() to finish. And that is one-threaded, but there is a fix for it, and you can read about it on this question, you could use node-worker, as they suggested, or you could try the other's answer solution.

0

You can try to make use of abort the PDFCreate() execution on unmounting of loader component using AbortController. For Example -

  • Firstly wrap the function code to promise and register callback for abort event. PDFCreate file

      var pdf = require("pdf-creator-node");
          const path = require("path");
          import fs from "fs-extra";
    
              export default async function PDFCreate(abortSignal) {
                  return new Promise(function (resolve, reject) {
                      // Wrap to promise
    
                      // register abort event
                      abortSignal.addEventListener("abort", () => {
                          // 6
                          const error = new DOMException(
                      "Calculation aborted by the user",
                      "AbortError"
                  );
                  reject(error); // 8
              });
    
              try {
                  var options = {
                      format: "A3",
                      orientation: "portrait",
                      border: "10mm",
                      header: {
                          height: "0mm",
                      },
                      footer: {
                          height: "28mm",
                          contents: {
                              first: "Cover page",
                              2: "Second page", // Any page number is working. 1-based index
                              default:
                                  '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
                              last: "Last Page",
                          },
                      },
                  };
                  console.log(path.join(__dirname));
                  const html = fs.readFileSync("app/data/file.html", "utf-8");
                  const bitmap = fs.readFileSync("public/images/lg.jpeg");
                  const logo = bitmap.toString("base64");
                  const filename = Math.random() + "_doc" + ".pdf";
    
                  const document = {
                      html: html,
                      data: {
                          logo,
                      },
                      path: "./docs/" + filename,
                  };
    
                  pdf
                      .create(document, options)
                      .then((res) => {
                          console.log(res);
                          resolve(); // Resolve on success
                      })
                      .catch((error) => {
                          console.log(error);
                      });
    
                  const filepath = "http://localhost:3000/public/images/" + filename;
                  return filepath;
              } catch (e) {
                  console.log(e);
                  throw e;
              }
          });
        }
    
  • Now initiate abortController in loader component and pass the abortController while calling PDFCreate() function. Call abortController.abort() on unmounting of loader component, maybe here you can use framework-specific component life-cycle method that. /PDF route

import PDFCreate from "~/data/createPDF.server";

export default async function loader() {
    let abortController = null;

    // Call abortController.abort when loader() component unmounts
    if (abortController) abortController.abort();

    try {
        abortController = new AbortController();
        await PDFCreate(abortController);
        return null;
    } catch (e) {
        abortController = null;
        console.log(e);
    }
  }
Sachin Som
  • 1,005
  • 3
  • 8