Skip to content

Introduction

Background task module. Provides child process task management and load balancing capabilities for running tasks outside the main Electron process.

Important

All Electron-related APIs cannot be used in child processes.

Core components:

  • ChildJob: Single task execution, creates a new child process each time. Acquire on demand, release when done. Suitable for infrequent tasks. When creating tasks frequently and in large quantities, there is process startup overhead — use ChildPoolJob instead.
  • ChildPoolJob: Process pool, maintains resident child processes, reuses them via load balancing. Avoids overhead of frequent process creation and destruction.
  • LoadBalancer: Load balancer, supports 8 scheduling algorithms for distributing tasks across processes.
  • AlgorithmType: Algorithm type constants.
  • Registry: registerJobManager() / killAllJobs() for central cleanup on application exit.

Import

Both CJS and ESM:

javascript
// ESM
import { ChildJob, ChildPoolJob, LoadBalancer, AlgorithmType } from 'ee-core/jobs';
import type { LoadBalancerTarget, LoadBalancerParams, LoadBalancerOptions } from 'ee-core/jobs';
import type { JobProcessOptions, JobMessage, ProcessMessage } from 'ee-core/jobs';
import type { ChildPoolOptions } from 'ee-core/jobs';
// CJS
const { ChildJob, ChildPoolJob, LoadBalancer, AlgorithmType } = require('ee-core/jobs');

ChildJob

Introduction

Single-task child process manager. Creates a new child_process.fork() for each exec() call. The child process must call Ps.exit() to terminate after task completion, otherwise it remains running and wastes resources.

Advantages: Acquire on demand, release when done, does not excessively occupy computer resources.

Limitations: Process startup overhead when creating tasks frequently and in large quantities. Use ChildPoolJob for that scenario.

Usage

javascript
import { ChildJob } from 'ee-core/jobs';
const job = new ChildJob();

API

job.jobs

Description: Property. Collection of active JobProcess instances keyed by PID. Processes are automatically removed when they exit or encounter errors. Returns: Record<number, JobProcess>

job.exec(filepath, params, opt)

Description: Start a new child process to execute a job file. Resolves the filepath to an absolute path via getFullpath(), creates a JobProcess, and dispatches a run command. Parameters:

ParameterTypeRequiredDescription
filepathstringYesRelative path from the ./jobs directory, or an absolute path
paramsRecord<string, unknown>NoParameters passed to the task
optJobProcessOptionsNoProcess options (processArgs, processOptions)

Returns: JobProcess — the child process instance Example:

javascript
const myProc = job.exec('./jobs/example/timer', { jobId: 'task-1' });

job.execPromise(filepath, params, opt)

Description: Async syntax for exec(). Creates a new child process to execute a job file. Returns the same JobProcess as exec(). Parameters: Same as exec()Returns: Promise<JobProcess> — the child process instance Example:

javascript
job.execPromise('./jobs/example/timer', { jobId }).then(task => {
  const eventName = 'job-timer-progress-' + jobId;
  task.emitter.on(eventName, (data) => {
    // handle progress
  });
});

job.createProcess(opt)

Description: Create a JobProcess instance without dispatching a command. Useful when you need a child process but want to send commands manually later. Parameters:

ParameterTypeRequiredDescription
optJobProcessOptionsNoProcess options (processArgs, processOptions)

Returns: JobProcess — the newly created process instance

job.getPids()

Description: Get the PID list of all active child processes. Parameters: None Returns: string[] — array of PID strings

job.on(eventName, callback)

Description: Listen to an event emitted by child processes. ChildJob inherits from EventEmitter. Note: When multiple child processes exist simultaneously, it may be difficult to distinguish the source — use JobProcess.emitter for per-process events. Parameters:

ParameterTypeRequiredDescription
eventNamestringYesEvent name
callbackFunctionYesEvent handler

Example:

javascript
// In service: ./electron/service/example.js
const eventName = 'job-timer-progress-' + jobId;
job.on(eventName, (data) => {
  // handle data from child process
});

// In job: ./electron/jobs/timer.js
import { childMessage } from 'ee-core/message';
const eventName = 'job-timer-progress-' + jobId;
childMessage.sendToMain(eventName, { jobId, number });

JobProcess (Entity)

The process object returned by exec(), execPromise(), or createProcess().

myProc.emitter

Description: An EventEmitter instance for per-process (forkProcess-level) events. Messages from the child process with eventReceiver: 'forkProcess' are emitted here. Returns: EventEmitter

myProc.child

Description: The ChildProcess object returned by child_process.fork(). See Node.js child_process docs. Returns: ChildProcess

myProc.pid

Description: Child process PID. Returns: number | undefined

myProc.dispatch(cmd, jobPath, ...params)

Description: Send a dispatch message to the child process. Generates a unique message ID and sends a JobMessage. Parameters:

ParameterTypeRequiredDescription
cmdstringYesCommand (e.g. 'run')
jobPathstringNoTask file path (default '')
paramsunknown[]NoAdditional parameters

Returns: void

myProc.callFunc(jobPath, funcName, ...params)

Description: Call a specified method on the task instance in the child process. Resolves the task file path to an absolute path and sends a run command with jobFunc and jobFuncParams. Parameters:

ParameterTypeRequiredDescription
jobPathstringNoTask file path (relative paths resolved to absolute)
funcNamestringNoMethod name to call on the task instance
paramsunknown[]NoMethod arguments

Returns: voidExample:

javascript
myProc.callFunc('./jobs/example/timer', 'pause', param1, param2);

myProc.kill(timeout)

Description: Terminate the child process. First sends SIGINT for graceful exit, then sends SIGKILL to force termination after timeout. Parameters:

ParameterTypeRequiredDescription
timeoutnumberNoTimeout in ms to wait for graceful exit (default: 1000)

Returns: void

ChildPoolJob

Introduction

Child process pool manager. Maintains a set of resident child processes, distributes tasks through a LoadBalancer. Avoids overhead of frequent process creation and destruction.

  • Pool size: min=3, max=6 (configurable)
  • Load balancing: supports multiple algorithms, default is polling (round-robin)
  • Process binding: binds specific IDs to fixed processes via boundMap (e.g. session binding)
  • Auto cleanup: child processes are automatically removed from the pool on exit/error

Usage

javascript
import { ChildPoolJob } from 'ee-core/jobs';
const pool = new ChildPoolJob();
await pool.create(3); // Create 3 child processes

Constructor

javascript
new ChildPoolJob(opt?)
ParameterTypeRequiredDescription
optChildPoolOptionsNoPool options

ChildPoolOptions:

FieldTypeRequiredDescription
weightsnumber[]NoWeight values for each process (used by weighted load balancing algorithms)

API

pool.children

Description: Property. Collection of active JobProcess instances keyed by PID. Returns: Record<number, JobProcess>

pool.boundMap

Description: Property. Binding map that maps boundId to PID. Ensures the same boundId is always assigned to the same child process (e.g. session binding). Returns: Map<string | number, number>

pool.min

Description: Property. Minimum number of processes in the pool (default: 3). Returns: number

pool.max

Description: Property. Maximum number of processes in the pool (default: 6). Returns: number

pool.strategy

Description: Property. Current load balancing strategy name (default: 'polling'). Returns: string

pool.weights

Description: Property. Weight array for each process position. Default weight is 1; can be customized via constructor options. Returns: number[]

pool.LB

Description: Property. The LoadBalancer instance used for process selection. Returns: LoadBalancer

pool.create(number)

Description: Create a specified number of child processes and add them to the pool and load balancer. The count is limited by max; excess processes will not be created. Parameters:

ParameterTypeRequiredDescription
numbernumberNoNumber of processes to create (default: 3)

Returns: Promise<string[]> — list of all process PIDs after creation Example:

javascript
pool.create(3).then(pids => {
  // pids: ['12345', '12346', '12347']
});

pool.run(filepath, params)

Description: Select a child process from the pool via the load balancer and execute a job file. Parameters:

ParameterTypeRequiredDescription
filepathstringYesRelative path from the ./jobs directory, or an absolute path
paramsRecord<string, unknown>NoParameters to pass to the task

Returns: Promise<JobProcess> — the child process instance executing the task Example:

javascript
const timerTask = await pool.run('./jobs/example/timer', { jobId });

pool.runPromise(filepath, params)

Description: Alias for run(). Async syntax for executing a task file via the pool. Parameters: Same as run()Returns: Promise<JobProcess>

pool.getBoundChild(boundId)

Description: Get a child process bound to a specific ID. The same boundId always returns the same process, suitable for session binding scenarios. If the bound process no longer exists, a new one is assigned and the binding is updated. Parameters:

ParameterTypeRequiredDescription
boundId`stringnumber`Yes

Returns: Promise<JobProcess> — the bound child process instance

pool.getChildByPid(pid)

Description: Get a child process by its PID. Parameters:

ParameterTypeRequiredDescription
pidnumberYesProcess ID

Returns: JobProcess | null

pool.getChild()

Description: Get an available child process from the pool. If the pool is empty, automatically creates one. Uses the load balancer to select a process. Parameters: None Returns: Promise<JobProcess> — the selected child process instance

pool.getPids()

Description: Get the PID list of all child processes in the pool. Parameters: None Returns: string[] — array of PID strings

pool.killAll(type)

Description: Kill all child processes in the pool. Parameters:

ParameterTypeRequiredDescription
type`'parallel''sequence'`No

Returns: void

pool.on(eventName, callback)

Description: Listen to pool-level events. ChildPoolJob inherits from EventEmitter. For per-process events, use JobProcess.emitter.

JobProcess (Entity)

Same entity as described in the ChildJob section above. Returned by run(), runPromise(), getBoundChild(), getChild().

LoadBalancer

Introduction

Load balancer for distributing tasks across child processes. Supports 8 scheduling algorithms. Based on the electron-re project with modifications.

Usage

javascript
import { LoadBalancer, AlgorithmType } from 'ee-core/jobs';

const lb = new LoadBalancer({
  targets: [{ id: 1, weight: 1 }, { id: 2, weight: 2 }],
  algorithm: AlgorithmType.polling,
});

Constructor

javascript
new LoadBalancer(options)
ParameterTypeRequiredDescription
optionsLoadBalancerOptionsYesConfiguration options
options.targetsLoadBalancerTarget[]YesTarget list [{id, weight}]
options.algorithmstringNoAlgorithm name (default: AlgorithmType.polling)

LoadBalancerTarget:

FieldTypeRequiredDescription
id`stringnumber`Yes
weightnumberNoWeight value (used by weighted algorithms)

LoadBalancerOptions:

FieldTypeRequiredDescription
targetsLoadBalancerTarget[]YesTarget list
algorithmstringNoAlgorithm name (default: 'polling')

API

LoadBalancer.Algorithm

Description: Static property. Reference to the AlgorithmType constants object for easy access to algorithm names. Returns: AlgorithmType

lb.pickOne(...params)

Description: Elect a single target process using the configured algorithm. Parameters:

ParameterTypeRequiredDescription
paramsunknown[]NoAdditional parameters for the algorithm (e.g. ID for specify algorithm)

Returns: LoadBalancerTarget | null — the selected target, or null if no targets available

lb.pickMulti(count, ...params)

Description: Elect multiple target processes by calling pickOne() repeatedly. Parameters:

ParameterTypeRequiredDescription
countnumberNoNumber of targets to select (default: 1)
paramsunknown[]NoAdditional parameters passed to each pickOne() call

Returns: (LoadBalancerTarget | null)[] — array of selected targets

lb.add(task)

Description: Add a target to the load balancer. If the target ID already exists, logs a warning and does nothing. Recalculates weight totals after adding. Parameters:

ParameterTypeRequiredDescription
taskLoadBalancerTargetYesTarget to add {id, weight}

Returns: void

lb.del(target)

Description: Delete a target from the load balancer. Removes from targets list, cleans up connection/occupancy maps, recalculates indices and weights. If the target ID is not found, logs a warning. Parameters:

ParameterTypeRequiredDescription
targetLoadBalancerTargetYesTarget to delete {id, weight}

Returns: void

lb.wipe()

Description: Remove all targets and reset all internal state (connections, occupancy maps, indices). Parameters: None Returns: void

lb.setTargets(targets)

Description: Replace the entire targets list. Cleans up state for targets that are no longer in the new list. Recalculates weight totals. Parameters:

ParameterTypeRequiredDescription
targetsLoadBalancerTarget[]YesNew targets list

Returns: void

lb.setAlgorithm(algorithm)

Description: Change the scheduling algorithm. Resets weight index. Throws an error if the algorithm name is not in AlgorithmType. Parameters:

ParameterTypeRequiredDescription
algorithmstringYesAlgorithm name from AlgorithmType

Returns: voidExample:

javascript
lb.setAlgorithm(AlgorithmType.weightsPolling);

lb.refreshParams(pidMap)

Description: Refresh CPU and memory occupancy data from process info. Used by minimum-connection and weighted-minimum-connection algorithms. Parameters:

ParameterTypeRequiredDescription
pidMap`Record<stringnumber, PidInfo>`Yes

PidInfo:

FieldTypeRequiredDescription
pid`stringnumber`Yes
cpunumberYesCPU usage
memorynumberYesMemory usage

Returns: void

lb.updateParams(object)

Description: Update specific load balancer runtime parameters (currentIndex, weightIndex, weightTotal, connectionsMap, etc.). Only updates keys that exist in LoadBalancerParams. Parameters:

ParameterTypeRequiredDescription
objectPartial<LoadBalancerParams>YesParameters to update

Returns: void

lb.clean(id)

Description: Clean up internal state. If id is provided, removes connection/occupancy data for that specific target. If no id, resets all internal maps while preserving weight totals. Parameters:

ParameterTypeRequiredDescription
id`stringnumber`No

Returns: void

Constants

AlgorithmType

Description: Load balancing algorithm type constants. Used to configure the LoadBalancer algorithm and ChildPoolJob strategy.

ConstantValueDescription
AlgorithmType.polling'polling'Round-robin: select the next target in sequence
AlgorithmType.weights'weights'Weighted: select by weight ratio
AlgorithmType.random'random'Random: randomly select a target
AlgorithmType.specify'specify'Specify: select a target by ID (requires id param)
AlgorithmType.weightsPolling'weightsPolling'Weighted round-robin: combines weight and sequential selection
AlgorithmType.weightsRandom'weightsRandom'Weighted random: combines weight and random selection
AlgorithmType.minimumConnection'minimumConnection'Least connections: select the target with fewest current connections
AlgorithmType.weightsMinimumConnection'weightsMinimumConnection'Weighted least connections: combines weight and least connections

Example:

javascript
import { AlgorithmType } from 'ee-core/jobs';

// Use in LoadBalancer
const lb = new LoadBalancer({
  targets: [{ id: 1, weight: 2 }, { id: 2, weight: 1 }],
  algorithm: AlgorithmType.weightsPolling,
});

// Use in ChildPoolJob
const pool = new ChildPoolJob({ weights: [2, 1, 1] });
pool.LB.setAlgorithm(AlgorithmType.weightsRandom);

Registry

registerJobManager(job)

Description: Register a job manager instance (ChildJob or ChildPoolJob) for centralized cleanup. Called after creating a ChildJob or ChildPoolJob to ensure all child processes are properly terminated when the application exits. Parameters:

ParameterTypeRequiredDescription
jobKillableYesJob manager instance (must have killAll() method, or getPids() + kill() methods)

Returns: voidExample:

javascript
import { ChildJob, registerJobManager } from 'ee-core/jobs';

const job = new ChildJob();
registerJobManager(job);

killAllJobs()

Description: Kill all registered job managers. Called in the Electron before-quit event to ensure all child processes are properly terminated and prevent process leaks. Prefers killAll() method; falls back to killing individual processes via getPids() + kill(). Parameters: None Returns: voidExample:

javascript
import { killAllJobs } from 'ee-core/jobs';

// Called during app quit lifecycle
killAllJobs();

See also: Registered automatically during framework lifecycle via before-quit event

Types

JobProcessOptions

Options when creating a JobProcess.

FieldTypeRequiredDescription
processArgsRecord<string, unknown>NoArguments object passed to the child process
processOptionsForkOptionsNoFork options (cwd, env, stdio, etc.)

JobMessage

Message format: Main process -> Child process.

FieldTypeRequiredDescription
midstringYesMessage ID (random string)
cmdstringYesCommand (e.g. 'run')
jobPathstringNoTask file path
jobParamsunknown[]NoTask constructor arguments
jobFuncstringNoInstance method name to call
jobFuncParamsunknown[]NoInstance method arguments

ProcessMessage

Message format: Child process -> Main process. Extends MessageData.

FieldTypeRequiredDescription
eventReceiverstringYesMessage receiver type: 'forkProcess', 'childJob', or 'all'
eventstringYesEvent name
dataunknownNoEvent data

LoadBalancerParams

Load balancer runtime parameters.

FieldTypeRequiredDescription
currentIndexnumberYesCurrent polling index
weightIndexnumberYesCurrent weight index (for weighted round-robin)
weightTotalnumberYesSum of all weights
connectionsMap`Record<stringnumber, number>`Yes
cpuOccupancyMap`Record<stringnumber, number>`Yes
memoryOccupancyMap`Record<stringnumber, number>`Yes