--- /dev/null
+---
+description: Reviews code.
+mode: subagent
+temperature: 0.1
+tools:
+ write: false
+ edit: false
+ bash: false
+---
+
+You are in code review mode. Focus on:
+
+- Code quality
+- Best practices
+- Algorithmic
+- Bugs
+- Edge cases
+- Performance
+- Security
+
+Provide constructive and detailed feedbacks.
--- /dev/null
+---
+description: Run code linter and formatter.
+---
+
+Run code linter and formatter with autofixes.
+Raw output:
+!`pnpm format`
+Summarize code linter or formatter failures and propose targeted fixes.
--- /dev/null
+---
+description: Run test suite.
+---
+
+Run test suite.
+Raw output:
+!`pnpm test`
+Summarize failing tests and propose targeted fixes.
--- /dev/null
+# Agent Guidelines for Poolifier
+
+## Build/Test Commands
+
+- `pnpm build` - Build for development
+- `pnpm test` - Run all tests
+- `pnpm test -- --grep "pattern"` - Run tests matching pattern
+- `pnpm lint` - Run ESLint
+- `pnpm format` - Format with Biome + ESLint fix
+
+## Code Style
+
+- **Imports**: Use `.js` extensions for TypeScript imports (Node16 module resolution)
+- **Naming**: camelCase for variables/functions, PascalCase for classes/types/interfaces
+- **Types**: Explicit types over `any`, use type guards and discriminated unions
+- **Async**: Prefer async/await over raw Promises, handle rejections with try/catch
+- **Formatting**: 2-space indent, single quotes, no semicolons, trailing commas (ES5)
+- **Error Handling**: Use typed errors with structured properties
+
+## Key Patterns
+
+- Export types with `export type {}` syntax
+- Use `.js` file extensions in imports even for `.ts` files
+- Follow established factory/strategy patterns for pool implementations
+- Maintain single source of truth for configuration defaults
+
+## Repository Rules
+
+See `.github/copilot-instructions.md` for comprehensive coding standards including DRY principles, naming coherence, and TypeScript conventions. Follow quality gates: lint, format, and test passes required.
import { bench, group, run } from 'tatami-ng'
/**
- *
- * @param numberOfWorkers
- * @param maxNumberOfTasksPerWorker
- * @returns
+ * Generates a random tasks map for benchmarking.
+ * @param numberOfWorkers - The number of workers.
+ * @param maxNumberOfTasksPerWorker - The maximum number of tasks per worker.
+ * @returns The generated tasks map.
*/
function generateRandomTasksMap (
numberOfWorkers,
const tasksMap = generateRandomTasksMap(60, 20)
/**
- *
- * @param tasksMap
- * @returns
+ * Selects the worker with least tasks using array sort.
+ * @param tasksMap - The tasks map.
+ * @returns The worker with least tasks.
*/
function arraySortSelect (tasksMap) {
const tasksArray = Array.from(tasksMap)
}
/**
- *
- * @param tasksMap
- * @returns
+ * Selects the worker with least tasks using loop iteration.
+ * @param tasksMap - The tasks map.
+ * @returns The worker with least tasks.
*/
function loopSelect (tasksMap) {
let minKey
}
/**
- *
- * @param array
- * @param leftIndex
- * @param rightIndex
- * @param pivotIndex
- * @param compare
- * @returns
+ * Partitions an array for quickselect algorithm.
+ * @param array - The array to partition.
+ * @param leftIndex - The left boundary index.
+ * @param rightIndex - The right boundary index.
+ * @param pivotIndex - The pivot element index.
+ * @param compare - The comparison function.
+ * @returns The new pivot index after partitioning.
*/
function partition (
array,
}
/**
- *
- * @param tasksMap
- * @returns
+ * Selects the worker with least tasks using quickselect loop algorithm.
+ * @param tasksMap - The tasks map.
+ * @returns The worker with least tasks.
*/
function quickSelectLoop (tasksMap) {
const tasksArray = Array.from(tasksMap)
}
/**
- *
- * @param tasksMap
- * @returns
+ * Selects the worker with least tasks using quickselect loop with random pivot.
+ * @param tasksMap - The tasks map.
+ * @returns The worker with least tasks.
*/
function quickSelectLoopRandomPivot (tasksMap) {
const tasksArray = Array.from(tasksMap)
}
/**
- *
- * @param tasksMap
- * @returns
+ * Selects the worker with least tasks using quickselect recursion algorithm.
+ * @param tasksMap - The tasks map.
+ * @returns The worker with least tasks.
*/
function quickSelectRecursion (tasksMap) {
const tasksArray = Array.from(tasksMap)
}
/**
- *
- * @param tasksMap
- * @returns
+ * Selects the worker with least tasks using quickselect recursion with random pivot.
+ * @param tasksMap - The tasks map.
+ * @returns The worker with least tasks.
*/
function quickSelectRecursionRandomPivot (tasksMap) {
const tasksArray = Array.from(tasksMap)
}
/**
- *
- * @param array
- * @param k
- * @param leftIndex
- * @param rightIndex
- * @param compare
- * @param pivotIndexSelect
- * @returns
+ * Selects the k-th smallest element using quickselect loop algorithm.
+ * @param array - The array to select from.
+ * @param k - The index of the element to select.
+ * @param leftIndex - The left boundary index.
+ * @param rightIndex - The right boundary index.
+ * @param compare - The comparison function.
+ * @param pivotIndexSelect - The pivot selection function.
+ * @returns The k-th smallest element.
*/
function selectLoop (
array,
}
/**
- *
- * @param array
- * @param k
- * @param leftIndex
- * @param rightIndex
- * @param compare
- * @param pivotIndexSelect
- * @returns
+ * Selects the k-th smallest element using quickselect recursion algorithm.
+ * @param array - The array to select from.
+ * @param k - The index of the element to select.
+ * @param leftIndex - The left boundary index.
+ * @param rightIndex - The right boundary index.
+ * @param compare - The comparison function.
+ * @param pivotIndexSelect - The pivot selection function.
+ * @returns The k-th smallest element.
*/
function selectRecursion (
array,
}
/**
- *
- * @param array
- * @param index1
- * @param index2
+ * Swaps two elements in an array.
+ * @param array - The array containing elements to swap.
+ * @param index1 - The index of the first element.
+ * @param index2 - The index of the second element.
*/
function swap (array, index1, index2) {
const tmp = array[index1]
import { bench, group, run } from 'tatami-ng'
/**
- *
- * @param numberOfWorkers
- * @returns
+ * Generates an array of worker indices.
+ * @param numberOfWorkers - The number of workers.
+ * @returns The array of worker indices.
*/
function generateWorkersArray (numberOfWorkers) {
return [...Array(numberOfWorkers).keys()]
let nextWorkerIndex
/**
- * @returns
+ * Round-robin worker selection using increment and modulo operation.
+ * @returns The selected worker.
*/
function roundRobinIncrementModulo () {
const chosenWorker = workers[nextWorkerIndex]
}
/**
- * @returns
+ * Round-robin worker selection using ternary operator with off-by-one logic.
+ * @returns The selected worker.
*/
function roundRobinTernaryOffByOne () {
nextWorkerIndex =
}
/**
- * @returns
+ * Round-robin worker selection using ternary operator with negation.
+ * @returns The selected worker.
*/
function roundRobinTernaryWithNegation () {
nextWorkerIndex =
}
/**
- * @returns
+ * Round-robin worker selection using ternary operator with pre-choosing.
+ * @returns The selected worker.
*/
function roundRobinTernaryWithPreChoosing () {
const chosenWorker = workers[nextWorkerIndex]
'Quadflieg',
'neostandard',
'poolifier',
+ 'quickselect',
],
},
},
import { ThreadWorker } from 'poolifier'
/**
- *
- * @param data
- * @returns
+ * First worker function example.
+ * @param data - The input data containing text.
+ * @returns The processed result with modified text.
*/
function fn0 (data) {
console.info('Executing fn0')
}
/**
- *
- * @param data
- * @returns
+ * Second worker function example.
+ * @param data - The input data containing text.
+ * @returns The processed result with modified text.
*/
function fn1 (data) {
console.info('Executing fn1')
import { ThreadWorker } from 'poolifier'
/**
- * @returns
+ * Example worker function that performs JSON serialization operations.
+ * @returns The result indicating successful completion.
*/
function yourFunction () {
for (let i = 0; i <= 1000; i++) {
--- /dev/null
+{
+ "$schema": "https://opencode.ai/config.json",
+ "formatter": {
+ "prettier": {
+ "disabled": true
+ }
+ }
+}
private writeIdx: number
/**
- * @param size - Buffer size. @defaultValue defaultBufferSize
+ * @param size - Buffer size.
+ * @defaultValue defaultBufferSize
* @returns CircularBuffer.
*/
constructor (size: number = defaultBufferSize) {
* Adds the given worker node in the pool worker nodes.
* @param workerNode - The worker node.
* @returns The added worker node key.
- * @throws {@link https://nodejs.org/api/errors.html#class-error} If the added worker node is not found.
+ * @throws {Error} If the added worker node is not found.
*/
private addWorkerNode (workerNode: IWorkerNode<Worker, Data>): number {
this.workerNodes.push(workerNode)
/**
* Checks if the worker id sent in the received message from a worker is valid.
* @param message - The received message.
- * @throws {@link https://nodejs.org/api/errors.html#class-error} If the worker id is invalid.
+ * @throws {Error} If the worker id is invalid.
*/
private checkMessageWorkerId (message: MessageValue<Data | Response>): void {
if (message.workerId == null) {
/**
* Starts the minimum number of workers.
- * @param initWorkerNodeUsage - Whether to initialize the worker node usage or not. @defaultValue false
+ * @param initWorkerNodeUsage - Whether to initialize the worker node usage or not.
+ * @defaultValue false
*/
private startMinimumNumberOfWorkers (initWorkerNodeUsage = false): void {
if (this.minimumNumberOfWorkers === 0) {
* @param name - The name of the task function.
* @param fn - The task function.
* @returns `true` if the task function was added, `false` otherwise.
- * @throws {@link https://nodejs.org/api/errors.html#class-typeerror} If the `name` parameter is not a string or an empty string.
- * @throws {@link https://nodejs.org/api/errors.html#class-typeerror} If the `fn` parameter is not a function or task function object.
+ * @throws {TypeError} If the `name` parameter is not a string or an empty string.
+ * @throws {TypeError} If the `fn` parameter is not a function or task function object.
*/
readonly addTaskFunction: (
name: string,
/**
* Worker choice strategies context constructor.
* @param pool - The pool instance.
- * @param workerChoiceStrategies - The worker choice strategies. @defaultValue [WorkerChoiceStrategies.ROUND_ROBIN]
+ * @param workerChoiceStrategies - The worker choice strategies.
+ * @defaultValue [WorkerChoiceStrategies.ROUND_ROBIN]
* @param opts - The worker choice strategy options.
*/
public constructor (
/**
* Executes the given worker choice strategy in the context algorithm.
- * @param workerChoiceStrategy - The worker choice strategy algorithm to execute. @defaultValue this.defaultWorkerChoiceStrategy
+ * @param workerChoiceStrategy - The worker choice strategy algorithm to execute.
+ * @defaultValue this.defaultWorkerChoiceStrategy
* @returns The key of the worker node.
- * @throws {@link https://nodejs.org/api/errors.html#class-error} If after computed retries the worker node key is null or undefined.
+ * @throws {Error} If after computed retries the worker node key is null or undefined.
*/
public execute (
workerChoiceStrategy: WorkerChoiceStrategy = this
* Executes the given worker choice strategy.
* @param workerChoiceStrategy - The worker choice strategy.
* @returns The key of the worker node.
- * @throws {@link https://nodejs.org/api/errors.html#class-error} If after computed retries the worker node key is null or undefined.
+ * @throws {Error} If after computed retries the worker node key is null or undefined.
*/
private executeStrategy (workerChoiceStrategy: IWorkerChoiceStrategy): number {
let workerNodeKey: number | undefined = workerChoiceStrategy.choose()
readonly dequeueLastPrioritizedTask: () => Task<Data> | undefined
/**
* Dequeue task.
- * @param bucket - The prioritized bucket to dequeue from. @defaultValue 0
+ * @param bucket - The prioritized bucket to dequeue from.
+ * @defaultValue 0
* @returns The dequeued task.
*/
readonly dequeueTask: (bucket?: number) => Task<Data> | undefined
/**
* Constructs a fixed queue.
- * @param size - Fixed queue size. @defaultValue defaultQueueSize
+ * @param size - Fixed queue size.
+ * @defaultValue defaultQueueSize
* @returns IFixedQueue.
*/
constructor (size: number = defaultQueueSize) {
/**
* Constructs a FixedPriorityQueue.
- * @param size - Fixed queue size. @defaultValue defaultQueueSize
+ * @param size - Fixed queue size.
+ * @defaultValue defaultQueueSize
* @param agingFactor - Aging factor to apply to items (priority points per millisecond).
* @param loadExponent - Load exponent applied to normalized load when computing effective aging.
* @returns IFixedQueue.
/**
* Constructs a priority queue.
- * @param bucketSize - Prioritized bucket size. @defaultValue defaultBucketSize
- * @param enablePriority - Whether to enable priority. @defaultValue false
+ * @param bucketSize - Prioritized bucket size.
+ * @defaultValue defaultBucketSize
+ * @param enablePriority - Whether to enable priority.
+ * @defaultValue false
* @returns PriorityQueue.
*/
public constructor (
* @param data - Data to enqueue.
* @param priority - Priority of the data. Lower values have higher priority.
* @returns The new size of the fixed queue.
- * @throws If the fixed queue is full.
+ * @throws {Error} If the fixed queue is full.
*/
enqueue: (data: T, priority?: number) => number
/**
/**
* Returns the main worker.
* @returns Reference to the main worker.
- * @throws {@link https://nodejs.org/api/errors.html#class-error} If the main worker is not set.
+ * @throws {Error} If the main worker is not set.
*/
protected getMainWorker (): MainWorker {
if (this.mainWorker == null) {
/**
* Check if the message worker id is set and matches the worker id.
* @param message - The message to check.
- * @throws {@link https://nodejs.org/api/errors.html#class-error} If the message worker id is not set or does not match the worker id.
+ * @throws {Error} If the message worker id is not set or does not match the worker id.
*/
private checkMessageWorkerId (message: MessageValue<Data>): void {
if (message.workerId == null) {
const { sleepTaskFunction } = require('../../test-utils.cjs')
/**
- *
- * @param data
- * @returns
+ * Test worker function that throws an error after sleeping.
+ * @param data - The task data.
+ * @returns The result after sleeping and potentially throwing an error.
*/
async function error (data) {
return sleepTaskFunction(
const { sleepTaskFunction } = require('../../test-utils.cjs')
/**
- *
- * @param data
- * @returns
+ * Test worker function that sleeps for a specified duration.
+ * @param data - The task data.
+ * @returns The result after sleeping.
*/
async function sleep (data) {
return sleepTaskFunction(data, 2000)
const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs')
/**
- *
- * @param data
- * @returns
+ * Test worker function that echoes the input data.
+ * @param data - The task data to echo.
+ * @returns The same data that was passed in.
*/
function echo (data) {
return data
const { sleepTaskFunction } = require('../../test-utils.cjs')
/**
- *
- * @param data
- * @returns
+ * Test worker function for long-running tasks with hard kill behavior.
+ * @param data - The task data.
+ * @returns The result after sleeping.
*/
async function sleep (data) {
return sleepTaskFunction(data, 50000)
const { sleepTaskFunction } = require('../../test-utils.cjs')
/**
- *
- * @param data
- * @returns
+ * Test worker function that performs a long-running sleep operation with soft behavior.
+ * @param data - The task data.
+ * @returns The result of the sleep operation.
*/
async function sleep (data) {
return sleepTaskFunction(data, 50000)
const { executeTaskFunction } = require('../../test-utils.cjs')
/**
- *
- * @param data
- * @returns
+ * Test worker function that executes configurable task functions for testing.
+ * @param data - The task data containing function configuration.
+ * @returns The result of the executed task function.
*/
function test (data) {
data = data || {}
import { sleepTaskFunction } from '../../test-utils.cjs'
/**
- *
- * @param data
- * @returns
+ * Test worker function that generates an asynchronous error for testing error handling.
+ * @param data - The task data.
+ * @returns Promise that rejects with an error message.
*/
async function error (data) {
return sleepTaskFunction(
import { sleepTaskFunction } from '../../test-utils.cjs'
/**
- *
- * @param data
- * @returns
+ * Test worker function that sleeps for a specified duration.
+ * @param data - The task data
+ * @returns The result after sleeping
*/
async function sleep (data) {
return sleepTaskFunction(data, 2000)
import { KillBehaviors, ThreadWorker } from '../../../lib/index.cjs'
/**
- *
- * @param data
- * @returns
+ * Test worker function that echoes the input data.
+ * @param data - The task data to echo
+ * @returns The same data that was passed in
*/
function echo (data) {
return data
import { sleepTaskFunction } from '../../test-utils.cjs'
/**
- *
- * @param data
- * @returns
+ * Test worker function for long-running tasks with hard kill behavior.
+ * @param data - The task data
+ * @returns The result after sleeping
*/
async function sleep (data) {
return sleepTaskFunction(data, 50000)
import { sleepTaskFunction } from '../../test-utils.cjs'
/**
- *
- * @param data
- * @returns
+ * Test worker function that performs a long-running sleep operation with soft behavior.
+ * @param data - The task data
+ * @returns The result of the sleep operation
*/
async function sleep (data) {
return sleepTaskFunction(data, 50000)
import { executeTaskFunction } from '../../test-utils.cjs'
/**
- *
- * @param data
- * @returns
+ * Test worker function that executes configurable task functions for testing.
+ * @param data - The task data containing function configuration
+ * @returns The result of the executed task function
*/
function test (data) {
data = data || {}