javascriptfirebasegoogle-cloud-functionsworker-threadnode-worker-threads

How to specify a local file path in Firebase Functions using worker_threads?


I have a firebase function that uses worker_threads to off load some cpu intensive tasks. To initialize the workerThread I give it a local file path to the worker file. But when the firebase function is executed I get the following error.

An error occurred: Error: Cannot find module '/workspace/worker.js'

The worker.js file resides in the same folder as the function calling new Worker(); they both live at the root level of the src directory.

I have tried using path.resolve with no avail. I can't find anything about using web workers AND firebase functions on the internet.

How do I specify the new Workers file path to find the file locally?

Reproduce:

File Structure:

lib
   - firebase_function.js
   - worker.js
   - index.js
src
   - firebase_function.ts
   - worker.ts
   - index.ts

1) Create a firebase v2 function:

import {onCall} from "firebase-functions/v2/https";
import {Worker} from "worker_threads";

const oncallablefunction = onCall(async (request) => {
    const result = await new Promise((resolve, reject) => {
        const worker = new Worker("./worker.js"); // <- errors here, file cannot be found
        worker.on('message', resolve);
        worker.on('error', reject);
    });

    // should be 1000
    console.log(result);
})

export {oncallablefunction}

2) Create worker.js file in the same directory as the firebase function

import {parentPort} from "worker_threads";

function doWork() {
    // do computation
    return 1000
}

const result = doWork()

if (parentPort) {
    parentPort.postMessage(result);
}

3) Export from index.js

import admin from "firebase-admin";

admin.initializeApp();

export * from './firebase_function.js';

4) Deploy and execute the oncallablefunction from firebase_function.js and get the following error:

Unhandled error Error: Cannot find module '/workspace/worker.js' at Function.Module._resolveFilename


Solution

  • Instead of specifying an absolute path which is subject to change. Use this to find the relative path:

    import path from 'path';
    import { fileURLToPath } from 'url';
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    
    path.resolve(__dirname, 'worker.js')