Search code examples
node.jsmultiprocessingenvironment-variables

How to set up `cluster.schedulingPolicy` in Node.js 18?


I am trying to run the loadtest module in cluster mode so it takes advantage of multiple cores. For the included test server it runs more efficiently using the cluster.schedulingPolicy of cluster.SCHED_NONE instead of the default round-robin cluster.SCHED_RR:

$ NODE_CLUSTER_SCHED_POLICY='none' node bin/testserver.js

I would prefer to set it up in code. The documentation says that I have to set it up in code:

cluster.schedulingPolicy = cluster.SCHED_NONE

This works fine with old-style require(), but there is a problem when using modern import:

import * as cluster from 'cluster'
cluster.schedulingPolicy = cluster.SCHED_NONE

It yields an error:

TypeError: Cannot assign to read only property 'schedulingPolicy' of object '[object Module]'

I have also tried importing just the variable:

import {schedulingPolicy} from 'cluster'

But this does not work. Setting the environment variable in code doesn't either:

process.env['NODE_CLUSTER_SCHED_POLICY'] = cluster.SCHED_NONE

It seems to change the value but then the children don't receive cluster.SCHED_NONE but cluster.SCHED_RR.

So, how am I supposed to set the schedulingPolicy other than with an environment variable set from outside Node.js?

Searching for an answer here has yielded no valid results, all were using require(). Thanks a lot!


Solution

  • I found a nasty workaround: since imports are always hoisted to the top of the file, setting the env variable before the import does not work. But if set the env variable and use a dynamic import afterwards, it works as expected. Short snippet showing the behaviour:

    process.env.NODE_CLUSTER_SCHED_POLICY = 'none'
    //import * as cluster from 'cluster'
    const cluster = await import('cluster')
    
    if (cluster.isPrimary) { 
        console.log(`process.env.NODE_CLUSTER_SCHED_POLICY: ${process.env.NODE_CLUSTER_SCHED_POLICY}`)
        for (let index = 0; index < 2; index++) { 
            cluster.fork()
            setTimeout(() => console.log(`cluster.schedulingPolicy: ${cluster.schedulingPolicy}`), 1000)
        } 
    } else { 
        setTimeout(() => null, 1000)
    }
    

    The issue has been reported to the Node.js core.