How do I access the global Strapi instance via a worker file?

Hey folks! I am having a bit of an issue accessing Strapi functions like strapi.entityService.findMany from a worker file.

TLDR I am using BullMQ and have a worker running on a seperate thread and file via workerThreads. In my src folder I added src/workers/myWorker.ts

Now, this worker file naturally doesn’t have access to the global Strapi instance (I’m getting ReferenceError: strapi is not defined)

My question now is how do I best access the instance to perform entity find and insert operations to my database?

One option I saw is to** init a new Strapi instance** for the worker but that seems like a big resourceful task and overkill?!

Worst case, I guess I could internally call the API but that seems like a big hack.

Anyone has an idea?

This topic has been created from a Discord post (1252861900715327598) to give it more visibility.
It will be on Read-Only mode here.
Join the conversation on Discord

Can’t you int worker with strapi instance?

I guess the problem here that worker and a strapi instance are on separate threads

So you can’t really have a strapi instance inside worker unless you initiate it on a worker thread

Instead you strapi instance should accept worker messages

would you mind elaborating on this? I did get it work doing the following but not sure if that’s a “good” way:

index.ts

`register({ strapi }) {
strapi.log.debug(“:building_construction: :construction: Setting up structured-listing-worker …”);

setUpStructuredListingWorker(strapi);

},`

src/workers/listingWorker.ts

`import { Strapi } from “@strapi/strapi”;
import { Job, Worker } from “bullmq”;
import structuredListingJob from “./structuredListingJob”;

let worker: Worker;

export function setUpStructuredListingWorker(strapi: Strapi): void {
worker = new Worker(
“structured-listing-queue”,
async (job: Job) => {
// Do something with job
return structuredListingJob(job, strapi);
},
{
connection: strapi.config.get(“queue.redisQueue”),
concurrency: 1,
useWorkerThreads: true,
}
);

worker.on(“completed”, (job) => {
console.log(
:building_construction: :white_check_mark: Structured Listing Worker | Job ${job.id} completed successfully.”
);
});`

So essentially I am passing the Strapi instance down all the way from the register function. Does that seem a good way to do it? I’m glad this is at least working but ultimately, my idea to have it run on a seperate thread was to give my CPU some space for webservice tasks while my worker does some heavy long-time taking AI processing in the background.

Well it’s really hard to tell

The question is, if your worker is actually on another thread already

Second question, I guess if it’s on another thread you have a kind of shallow copy, or a shallow instance, e.g. a snapshot of some sort of strapi during register phase

In any case I’m guessing that you should be ok with running entity service or db query that way

You should be safe unless you have like a second instance of router running on a second thread, so both response

The only problem I see that your worker thread would access some protected system resource, like you would upload a file on both threads

Yeah I think in the implementation I showed up above I doubt it’s running on a seperate thread. According to the bullmq docs you can run it on a separate thread if you run from a separate file. I actually don’t need any sort of session context of Strapi in my worker file the only thing I want is to be able to conveniently use the entity service api to interact with my DB as setting up a secure REST endpoint just for the worker seems a bit weird?! But perhaps that’s OK to do? I very new to workers so not sure.

In general, is strapi intended to be used via global scope in any file?

Assuming same thread and not a worker. (I set up my bullmq worker in the above way.)

Or are we supposed to pass strapi into every helper function call etc