bree

repository·master·Indexed 25 days ago

https://github.com/breejs/bree

A lightweight and fast job scheduler for Node.js (v12.17.0+) and JavaScript. It uses worker threads to spawn sandboxed processes and supports cron, dates, ms, later, and human-friendly intervals. Key features include async/await support, retries, throttling, concurrency control, and graceful shutdowns.

Tokens
8.6K
Snippets
12
Records
41
Agent score
84%

What's inside bree

  1. Overview of Bree

    master

    Bree is a lightweight job scheduler for Node.js that supports various scheduling methods including cron, dates, ms (milliseconds), later (using the later library), and human-friendly time representations.

    Key features include:

    • Uses Node.js worker_threads to spawn sandboxed processes.
    • Supports async/await and Promises.
    • Built-in support for retries, throttling, and concurrency control.
    • Supports cancelable jobs with graceful shutdown.
    • Works with Node v12.17.0+.
  2. Upgrade Bree

    master

    If you are upgrading from a previous major version, please refer to the UPGRADING.md file for breaking changes.

    Note on breaking changes: Bree v9.0.0 introduced several breaking changes.

    Note on Node.js compatibility: Bree v6.5.0 is the last version to support Node v10 and browsers.

  3. Upgrade Bree from v8 to v9

    master

    Upgrading to v9 introduces several breaking changes, primarily moving from synchronous to asynchronous method calls and changing how debug logging is handled.

    Breaking Changes

    1. Asynchronous Methods: The following methods now return Promises and must be awaited:

      • bree.start()
      • bree.run()
      • bree.add()
      • bree.init() (internal, but relevant if you call it manually)
      • bree.stop() (returns a Promise, but awaiting is optional if start() or run() was already awaited).
    2. Debug Logging: Bree has switched from the debug package to util.debuglog. To enable debug logging, use the NODE_DEBUG environment variable instead of DEBUG.

      • Old: DEBUG=bree node app.js
      • New: NODE_DEBUG=bree node app.js
    3. ESM Support and File Resolution:

      • Bree now supports ECMAScript modules (ESM) via dynamic imports.
      • If you use index.mjs instead of index.js, you must set the defaultRootIndex option to ensure correct file resolution.

    Node.js Version Requirements

    • Bree works in Node v12.17+.
    • If you are on Node <= v12.20.0, it is highly recommended to upgrade to at least Node v14 or a current LTS version.
  4. Initialize Bree with ECMAScript modules (ESM)

    master

    To use Bree in an ESM environment (e.g., .mjs files), import Bree and call bree.start(). Note that top-level await is supported in Node.js v14.8+.

    // app.mjs
    
    import Bree from 'bree';
    
    const bree = new Bree({
      // ... (see below) ...
    });
    
    // top-level await supported in Node v14.8+
    await bree.start();
    
    // ... (see below) ...
  5. Signal job completion in workers

    master

    Since jobs run in worker threads, you must explicitly signal completion to the main thread. Use one of the following methods:

    1. Send a message: Use parentPort.postMessage('done'); to signal completion.
    2. Exit successfully: Call process.exit(0); if there is no error.
    3. Throw an error: Throwing an error will bubble up to the worker's error listener and terminate the worker.
    4. Exit with error: Call process.exit(1); if an error occurred.
  6. Configure the Bree root option for TypeScript

    master

    When using transpilers with Bree, it is recommended to explicitly set the root option to ensure job paths are resolved correctly.

    • For CommonJS: Use path.join(__dirname, 'jobs').
    • For ESModules: Use path.join(path.dirname(fileURLToPath(import.meta.url)), 'jobs') because __dirname is unavailable in ESM.
  7. Use TS Node for TypeScript development with Bree

    master

    To write jobs in TypeScript and have them transpiled on the fly using ts-node, you must run Bree in a way that allows ts-node to transpile child processes and worker scripts.

    1. Add a dev script to your package.json using the following command: "dev": "TS_NODE=true NODE_OPTIONS="-r ts-node/register" node ."
    2. Use the TS_NODE=true environment variable. This allows you to append .ts extensions to your worker paths in development, while using default .js extensions when running compiled code in production.
    "dev": "TS_NODE=true NODE_OPTIONS=\"-r ts-node/register\" node ."
  8. Compile Bree jobs to ESModules

    master

    To use Bree with ESModules and TypeScript, follow these configuration steps:

    1. Set "type": "module" in your package.json.
    2. Configure your TypeScript compiler (tsconfig.json) with:
      • moduleResolution: "node"
      • module: An option that outputs ESModule syntax (e.g., "ESNext" or "ES6").
    3. Update your dev script to use the ts-node ESM loader: "dev": "TS_NODE=true NODE_OPTIONS="--loader ts-node/esm" node ."
    "dev": "TS_NODE=true NODE_OPTIONS=\"--loader ts-node/esm\" node ."
  9. Configure Bree for TypeScript and Bundlers

    master

    When using bundlers (like Webpack or esbuild) or TypeScript, jobs must be treated as separate entry points because they run in independent worker threads and are not part of the main application's dependency graph.

    Best Practices:

    1. Configure your bundler to output jobs into a specific folder (e.g., dist/jobs).
    2. Set the root option in Bree to ensure it finds the jobs folder relative to your execution entry point.
    3. Ensure each job is transformed/transpiled just like your application code.

    Example structure:

    - dist
      |- jobs
        |- job.js
      |- index.js
  10. Upgrade Bree from v7 to v8

    master

    When upgrading from v7 to v8, note the following changes:

    1. Map Conversion: Several configuration fields have been converted from Objects to Maps. You can no longer access them via dot notation (e.g., bree.workers.NAME). Instead, use the .get() method.

      • Affected fields: closeWorkerAfterMs, workers, timeouts, and intervals.
      • Example: Use bree.workers.get(NAME) instead of bree.workers.NAME.
    2. Start Error: The start() method will now throw an error if the job has already been started.

  11. Implement an Email Queue using Bree

    master
    To build an email queue, use bree to schedule a job that periodically fetches pending email records from a database (like MongoDB or a SQL table) and sends them using a library like Nodemailer. It is highly recommended to use the email-templates package alongside bree for template management and local development previews.