HB's Thoughts

I try to think really hard.

7/3/2024

Log info with Web Workers from Vue 3 to the server

Web Workers are small, powerful scripts that run in the browser's background. And because they don't interfere with the rendering of your application, you can load them with various tasks to perform.

I use Web Workers in two ways - in the first one, they don't return information to the application and after finishing the work, they self-destruct. In the second one, they return a result and then the application takes care of when and if the Web Worker should be destroyed. Here we will look at only the first way of working. I will write a separate article for the second one.

LOG WORKER

I most often use the first way of working for Web Workers to log information from the application to the server, but not only.

I create a directory called workers and in it, I create a file - in our case LOGS.ts. The file is always in capital letters, so I can easily recognize it when importing it, and has a speaking name. Over time, I have concluded that every type of task that a given Web Worker performs should be in a separate file.

// workers/LOGS.ts

import axios from "axios";

self.onmessage = async (event) => {
  const { message, code, type } = event.data;
  await axios.post("/api/log", { type: `${message}`, statusCode: code }, { contentType: "text/plain" });

  /**
   * Log Worker does not return data,
   * so we close the worker after the POST request,
   * even if there is an error with writing to the server,
   * the worker will close.
   */
  self.close();
};

To use Web Workers in your application, you need to be very careful with its import. For Vue 3 with Composition API and <script lang='ts' setup>, there is a special directive worker, similar to a query string in the file path.

import LOGS from "~/workers/LOGS?worker";

Using it is easy and most often I call it from a try-catch block to write the errors to the server.

// criticalJob.vue

<script lang='ts' setup>
import LOGS from "~/workers/LOGS?worker";

const doSomeCriticalJob = async (id: string) => {
  try {
    // await do some critical job
  } catch (error) {
    const logsWorker = new LOGS();
    logsWorker.postMessage({ message: `Critical Job with ID: ${id} got error: ${error}`, code: 500, type: "error" });
  }
};
</script>

<template></template>

If you have an opinion or questions about the article, don't hesitate to share them.

Join the open discussion on GitHub.


Competence: Geek