npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

covey

v1.2.0

Published

Declarative process manager for long- and short-running background worker processes, most useful in Electron and CLI apps, and servers with heavy CPU-bound loads.

Downloads

32

Readme

covey

Covey is a Node.js manager for long- or short-running background processes.

Using Covey, you declaratively state what work you want done, and Covey will make sure that the work is completed.

Covey is similar to forever or worker-manager in that it is a useful way of keeping a long-running process alive and retrying on exits. It is different in that it is only meant for managing Node.js processes that adhere to a specific interface that need to convey status and completion information.

Covey is useful for splitting up an application into multiple independent pieces in situations where you need processes to be resilient to crashing and block the event loop more than normal, or when you simply want to declaratively sequence an application.

Limitations

Covey is probably better-suited for CLI utilities and Electron applications than server applications. Currently covey will only run one worker per process, and will not reuse processes.

In addition, errors are usually thrown globally instead of simply notifying interested parties. This makes a CoveyManager in "host mode" very vulnerable to crashes, which is acceptable for usage in Electron apps under controlled environment, but not with many users.

Because Covey uses introspection to get worker constructor names, you cannot currently use UglifyJS name mangling with your workers.

Roadmap

  • option to completely nuke a group, reset, stop, and clear all workers inside
  • Test multiple groups - no duplicate workers across groups
  • Test running bogus headless runner
  • Add support for results and data but as a proper pubsub channel, readable stream, promise
    • support streaming data within a reduxy app, to stream input
  • Add support for health checks
  • Add support for logging, especially across IPC boundaries
  • Add examples, in vanilla JS and TypeScript
  • Better story and testing around error handling in general
  • Better story around handling workers that refuse to stop
  • Maybe get rid of client / host manager stuff or simplify it
  • Document foreign process workers, managers, manager clients/hosts, headless runners

Concepts

Covey Manager

A Covey Manager is an object that manages covey workers - usually one process per application will be responsible for managing workers.

Covey Workers

A class that adheres to the CoveyWorker interface and a process that runs the worker.

Covey Group

A Covey Group is a named grouping of CoveyWorkers within a CoveyManager. You can set a group declaratively ("here is a list of all workers I want run in this group"): the manager will diff declared workers with existing workers; new workers will be started, workers that are no longer listed are torn down, and workers in both sets are untouched. You can also use groups in a less declarative way to add new workers or remove existing workers.

Usage

Declare a worker:

import { CoveyWorker, CoveyWorkerLifecycleState } from 'covey';
import SerialPort from 'serialport';
import http from 'http';

const { Crashed, Stopping, Stopped } = CoveyWorkerLifecycleState;

class StreamSerialPortToHttp extends CoveyWorker {
  params: {
    serialport:string,
    baudrate:number,
    port:number,
  };

  /**
   * A worker constructor must complete synchronously, and should take
   * configuration. It may synchronously validate input.
   * All parameters must be JSON-serializable!
   */
  constructor (serialport: string, baudrate: number, port: number) {
    super();
    this.params = {
      serialport,
      baudrate,
      port
    };
  }

  /**
   * Called a maximum of once per worker instance.
   */
  runWorker () {
    this.starting('begin'); // status update

    const s = new SerialPort(this.serialport, { baudRate: this.baudrate });

    this.state.serialLink = s;

    s.on('open', () => {
      this.starting('serial port opened'); // status update

      const responder = (req, res) => {
        s.pipe(res);
      };

      const server = http.createServer(responder).listen(this.port);

      this.state.server = server;

      server.on('close', () => {
        this.state.server = null;
        if (this.lifecycle.state !== Stopping) {
          this.crashed('http server closed');
        } else if (!this.state.serialLink) {
          this.stopped('stopped cleanly (from server close)');
        }
      });
    });

    s.on('close', () => {
      this.state.serialLink = null;
      if (this.lifecycle.state !== Stopping) {
        this.crashed('serial port closed');
      } else if (!this.state.server) {
        this.stopped('stopped cleanly (from serialLink close)');
      }
    });
  }

  /**
   * Called by worker manager or end-user to stop this worker.
   */
  stopWorker () {
    this.stopping('closing serial link and server');
    this.state.serialLink && this.state.serialLink.close();
    this.state.server && this.state.serialLink.close();
    // should be closed cleanly once server and serial link are closed
  }
}

Declare available workers in a manifest:

import { CoveyManifest } from 'covey';

const manifest = new CoveyManifest();

// Declare previously defined worker
manifest.declare(StreamSerialPortToHttp);

Then, create a manager somewhere with a manifest of available workers, and the standalone script that can be called to start foreign-process workers (optional):

import { CoveyManager } from 'covey';

const mgr = new CoveyManager(manifest, './worker.js');

Finally, communicate with your manager to start a group of workers:

import { CoveyGroup } from 'covey';

mgr.runGroup(new CoveyGroup('myWorkers', [
  new StreamSerialPortToHttp('/dev/tty.123', 9600, 7770).setOptions({ foreign: true }),
  new StreamSerialPortToHttp('/dev/tty.234', 115200, 7771).setOptions({ foreign: true }),
  new StreamSerialPortToHttp('/dev/tty.345', 921600, 7772).setOptions({ foreign: true })
]));

In addition to the options specific to a type of worker, all workers have common options like foreign, which defaults to true (foreign workers are run in their own process; non-foreign workers are run in the same process as the manager).

Then, you can subscribe to manager events to receive notifications about workers, query state, and perform other actions: TODO