Job queues and scheduled jobs for Node.js, Beanstalkd and/or Iron.io.

Related tags

Job Queues ironium
Overview

Ironium

Job queues and scheduled jobs for Node.js backed by Beanstalk/IronMQ/SQS.

The Why

You've got a workload that runs outside the Web app's request/response cycle. Some jobs are queued, some are scheduled. You decided to use Beanstalk and/or IronMQ. Now you need a simple API to code against, that will handle all the run-time intricacies for you.

Beanstalk is "a simple, fast work queue". It's easy to setup (brew install beanstalkd on the Mac), easy to tinker with (telnet localhost 11300), and persistently reliable.

IronMQ is "the Message Queue for the Cloud". It's a managed queue service with a nice UI, an excellent choice for production systems. And can handle much of the webhooks workload for you.

SQS is Amazon Web Services' fully managed queues product. It supports FIFO queues, dead-letter queues, and can be connected with SNS. Another great choice if you're into AWS.

The thing is, standalone Beanstalk is great for development and testing, I just don't want to manage a production server. IronMQ and SQS are wonderful services, but painful to use for development/testing.

Ironium allows you to use either/all in the same project.

API

Ironium has a simple API with three primary methods:

  • queueJob to push a job into a queue
  • eachJob to process all jobs from the queue
  • scheduleJob to run a job on a given schedule

There are a few more methods to help you with managing workers, running tests, and working with webhooks.

queue(queueName)

Returns the named queue. Calling this method with the same name will always return the same queue. Queues are created on-the-fly, you don't need to setup anything before accessing a queue.

You can immediately push new jobs into the queue. To process all jobs, you need to first start the workers. This distinction allows you to push jobs from any Node.js servers, but only process jobs from specific nodes.

For example, your code may have:

const Ironium          = require('ironium');
const sendWelcomeEmail = Ironium.queue('send-welcome-email');

// If this is a new customer, queue sending welcome email.
customer.on('save', function(next) {
  if (this.isNew)
    sendWelcomeEmail.queueJob(this.id)
      .then(() => next())
      .catch(next);
  else
    next();
});

sendWelcomeEmail.eachJob(function(id) {
  // Do something to render and send email
  return Promise.resolve();
});

As you can see from this example, each queue has three interesting methods, queueJob, delayJob and eachJob.

queueJob(queueName, job)

queue.queueJob(job)

Pushes a new job into the queue. The job is serialized as JSON, so objects, arrays and strings all work as expected.

Returns a promise that resolves to the job ID.

Calling Ironium.queueJob(name, job) is the same as Ironium.queue(name).queueJob(job).

For example:

const echoQueue = Ironium.queue('echo');

const job = {
  message: 'wow, such workers, much concurrency'
};

echoQueue.queueJob(job, function(error) {
  if (error)
    console.error('No echo for you!');
});

Because this function returns a promise, you can also do this in your test suite:

before(()=> echoQueue.queueJob(job));

And this, if you're using ES7:

await echoQueue.queueJob(job);

queue.queueJobs(jobs)

Same as queueJob but usually more efficient if you're queuing multiple jobs.

queue.delayJob(job, duration)

Similar to queueJob but delays processing of the job by the set duration.

Duration is either a number or a string. The default unit is milliseconds, but you can specify a string with units, such as "5m" or "3 hours".

Valid units are ms, seconds, minutes, hours, days and years. You can write each unit as plural ("1 hours"), singular ("1 hour") or first letter only ("1h").

eachJob(queueName, handler)

queue.eachJob(handler)

Processes jobs from the queue. In addition to calling this method, you need to either start the workers (see start method), or run all queued jobs once (see runOnce).

The job handler is a function that takes one argument: the job payload.

The job handler must return a promise that resolves when the job completes.

For example:

Ironium.queue('echo').eachJob(async function(job) {
  console.log('Echo', job.message);
  await fnReturningPromise();
  await anotherAsyncFunction();
});

Using vanilla promises:

Ironium.queue('echo').eachJob(function(job) {
  console.log('Echo', job.message);
  return fnReturningPromise()
    .then(anotherAsyncFunction);
});

The promise must be resolved within 10 minutes. Jobs that don't complete within that time frame are considered to have failed, and returned to the queue. Timeouts are necessary evil, given that jobs may fail to report completion and the halting problem is still NP hard.

If a failed job is returned to the queue, it will go into the delayed state and stay there for a few minutes, before it can be picked up again. This delay prevents processing bugs and transient errors (e.g. connection issues) from resulting in a DoS attack on your error log.

You can attach multiple handlers to the same queue, and each job will go to all the handlers. If any handler fails to process the job, it will return to the queue.

When processing webhooks, some services send valid JSON objects, while other services send text strings, so be ready to process those as well. For example, some services send form encoded pairs, so you may need to handle them like this:

const QS = require('querystring');

Ironium.queue('webhook').eachJob(function(job) {
  const params = QS.parse(job);
  console.log(params.message);
  return Promise.resolve();
});

queue.stream()

You can use this to queue jobs from a Node stream. It returns a duplex stream to which you can write a stream of jobs, and read back a stream of job IDs.

For example:

source
  .pipe(queue.stream())
  .pipe(process.stdout);

queue.name

This property returns the queue name.

This name does not include the prefix.

webhookURL(queueName)

This method resolves to the webhook URL of the named queue.

Since configuration can load asynchronously, this method returns a promise, not the actual URL. The webhook URL only makes sense when using IronMQ, Beanstalk and SQS do not support this feature.

NOTE: The webhook URL includes your project ID and access token, so be careful where you share it.

scheduleJob(jobName, when, handler)

Schedules the named job to run at the specified time.

Each schedule has a unique name, this is used for reporting, and to prevent accidental duplicate schedules. However, you can create two schedules using the same job.

The scheduled time can be a Date, in which case the job will run once at the given time. It can be an interval, in which case the job will run repeatedly at the given interval. The interval can be number (in ms), or a string that can takes the form of "90s", "5m", "4h", etc. The minimum interval is 60 seconds.

The scheduled time can also be an object with the properties start, end and every. If the property every is specified, the job will run every so many milliseconds.

If the property start is specified, the job will run once at the specified time, and if every is also specified, repeatedly afterwards. If the property end is specified, the job will stop running after that time.

Just like a queued job, the scheduled job handler is expected to return a promise that resolves on job completion.

For example:

Ironium.scheduleJob('inAnHour', new Date().getTime() + ms('1h'), function() {
  console.log("I run once, after an hour");
  return Promise.resolve();
});

const schedule = {
  every: ms('2h'),                         // Every two hours
  end:   new Date().getTime() + ms('24h'), // End in 24 hours
};
Ironium.scheduleJob('everyTwoForADay', schedule, async function() {
  console.log("I run every 2 hours for 24 hours");
  const customers = await Customer.findAll();
  for (const customer of customers)
    await customer.increase('awesome');
});

configure(object | promise)

Configure the workers, see Configuring.

start()

You must call this method to start the workers. Until you call this method, no scheduled or queued jobs are processed.

The start method allows you to run the same codebase in multiple environments, but only enable processing on select servers. For testing, have a look at runOnce.

stop()

You can call this method to stop the workers.

resetSchedule()

Reset the next run time for all scheduled jobs. Used during testing when changing the system clock to test scheduled jobs, in particular, rewinding the clock.

Ironium.scheduleJob('every-night', '24h', runEveryNight);

TimeKeeper.travel('2015-06-30T15:00:00Z');
Ironium.resetSchedule();
// Job now scheduled for 7/1 00:00 because it will run every 24 hours,
// starting at 00:00 on the next day

Ironium.runOnce(); // Nothing happens

TimeKeeper.travel('2015-07-01T00:00:00Z');
Ironium.runOnce();
// Job runs once, now scheduled for 7/2 00:00

TimeKeeper.travel('2015-06-30T15:00:00Z');
Ironium.runOnce();
// Nothing happens because next run is 7/2

Ironium.resetSchedule();
// Job now scheduled for 7/1 00:00 again

runOnce()

Use this method when testing. It will run all schedules jobs, and then process all queued jobs until the queues are empty.

Returns a promise that resolves when all jobs have been processed.

This method exists since there's no reliable way to use start and stop for running automated tests.

With regards to scheduled jobs, each job has a schedule when it will run next. Calling runOnce will run that job if its time has come. It will also adjust the next time the job should run. You may also need to use resetSchedule.

For example:

const queue = Ironium.queue('echo');
const echo  = [];

Ironium.scheduleJob('echo-foo', '24h', function() {
  return queue.queueJob('foo');
});

queue.eachJob(function(text) {
  echo.push(text);
  return Promise.resolve();
});


before(function() {
  TimeKeeper.travel('2015-06-30T12:00:00Z');
  Ironium.resetSchedule();
  // Job now scheduled for 7/1 at 00:00
});

// Queue another job
before(function() {
  return queue.queueJob('bar');
});

before(function() {
  // Running the scheduled job, followed by the two queued jobs
  TimeKeeper.travel(ms('2hr'));
  // Returns a promise, Mocha will wait for it to resolve
  return Ironium.runOnce();
});

it("should have run the foo scheduled job", function() {
  assert(echo.indexOf('foo') >= 0);
});

it("should have run the bar job", function() {
  assert(echo.indexOf('bar') >= 0);
});

after(function() {
  TimeKeeper.reset();
  Ironium.resetSchedule();
});

Both scheduled and delayed jobs can be tested by mocking Date, also known as time traveling by tools like TimeKeeper.

purgeQueues()

Use this method when testing. It will delete all queued jobs.

Returns a promise that resolves when all jobs have been deleted.

For example:

before(Ironium.purgeQueues);

Is equivalent to:

before(function() {
  return Ironium.purgeQueues();
});

Note: Mocha before/after runners accept functions that return a promise. This is the case for the methods start, stop, runOnce and purgeQueues. In addition, since these methods are bound to an instance of Ironium, you can pass the method directly as an argument to before or after.

Logging

By default Ironium produces no messages to the console. You can ask it to log to the console by setting the DEBUG environment variable to ironium or ironium:* (for more information, see debug).

For example:

# See processing errors
DEBUG=ironium npm start
# See queues and scheduling activity
DEBUG=ironium:queues:*,ironium:schedules npm start
# See activity on specific queue
DEBUG=ironium:queues:foobar npm start
# Everything
DEBUG=ironium:* npm start

In addition, you can register a callback to be notified of job processing errors:

Ironium.onerror(function(error, subject) {
  console.error('Error reported by', subject);
  console.error(error.stack);
});

Because Ironium expects some jobs will fail, and will retry them until successful, you do not have to listen to its error event. This event will not cause the program to exit.

Configuring

For development and testing you can typically get by with the default configuration. For production, you may want to set the server in use, as simple as passing a configuration object to Ironium.configure:

const Ironium = require('ironium');

if (process.env.NODE_ENV === 'production')
  Ironium.configure({
    host: 'my.beanstalkd.server'
  });

Or load it form a JSON configuration file:

const Ironium = require('ironium');
const config  = require('./iron.json');

if (process.env.NODE_ENV === 'production')
  Ironium.configure(config);

You can also use a promise that resolves to an object with all configuration properties.

The configuration options are:

{
  "host":         <hostname, optional>,
  "project_id":   <project ID from credentials settings>,
  "token":        <access token for this project>,
  "prefix":       <prefix all queue names>,
  "concurrency":  <number of jobs processed concurrently>
}

If you're running in development or test environment with a local Beanstalkd server, you can just use the default configuration, which points to localhost, port 11300.

The default configuration when running in test environment (NODE_ENV === 'test') uses the prefix test- for all queues.

If you're running in production against a Beanstalkd, you will likely need to set queues.host and queues.port.

If you're running in production against Iron.io, you need to set host, project_id and token based on your project credentials. This is the same format as iron.json.

By default, Ironium will process 50 jobs concurrently. You can change this value using the concurrency option or by setting the IRONIUM_CONCURRENCY environment variable.

Processing a subset of queues

If you want to isolate workloads, you can tell Ironium to only process some of the queues.

For simple whitelisting, use the IRONIUM_QUEUES environment variable:

env IRONIUM_QUEUES=queue1,queue2 npm start

For more advanced behavior, pass your own function in the configuration:

Ironium.configure({
  canStartQueue(queueName) {
    return queueName.startsWith('some-prefix');
  }
});

Testing Your Code

The default test configuration (NODE_ENV === 'test') connects to Beanstalkd on localhost, and prefixes all queue names with test-, so they don't conflict with any queues used during development.

Codeship has Beanstalkd installed on test servers, if using Travis, you will need to install it specifically, see our .travis.yml.

Contributing

Ironium is written in ECMAScript 6, because future.

You can run the entire test suite with npm test (Travis runs this), or specific files/tests with Mocha.

Comments
  • Add feature to Ironium to test delayed jobs with Timekeeper in test enviroment

    Add feature to Ironium to test delayed jobs with Timekeeper in test enviroment

    Issue: https://github.com/assaf/ironium/issues/48

    • Currently, there is no easy way to determine when a delayedJob has been processed without moving the system time forward (stubbing system time, or waiting out the duration with setTimeout)
    • Solution: keep track of the queued time a of a job in a data structure, and kick the job when the queued time + the duration of the delay is less than or the same as the current time (Date.now). Allows the user to test one or more delayed jobs in test environment with Timekeeper.
    • Also: fixes an assertion in delayedJobs where toString is not called in the assertion (?)
    opened by ugotsoul 19
  • Error queuing to tasks: Unknown error

    Error queuing to tasks: Unknown error

    My logs occasionally contain this error. Looking at the code it seems to be a connection error when posting a job to iron.io. I think those jobs simply get lost and I am not quite sure how to handle those cases. I am actually a bit uncertain if the problem is the iron.io API or something being stuck in ironium or node, because it would seem very unusual that the iron.io API is unreachable for the period of time these errors occur.

    Error queuing to tasks: Unknown error
    at /pipeline/source/node_modules/ironium/lib/queues.js:173:20
    at /pipeline/source/node_modules/iron_mq/lib/client.js:235:18
    at APIClient.Client.parseResponse (/pipeline/source/node_modules/iron_core/lib/client.js:251:18)
    at /pipeline/source/node_modules/iron_mq/lib/api_client.js:165:16
    at Request._callback (/pipeline/source/node_modules/iron_core/lib/client.js:180:20)
    at Request.self.callback (/pipeline/source/node_modules/iron_core/node_modules/request/request.js:344:22)
    at emitTwo (events.js:100:13)
    at Request.emit (events.js:185:7)
    at Request.<anonymous> (/pipeline/source/node_modules/iron_core/node_modules/request/request.js:1239:14)
    at emitOne (events.js:95:20)
    at Request.emit (events.js:182:7)
    at IncomingMessage.<anonymous> (/pipeline/source/node_modules/iron_core/node_modules/request/request.js:1187:12)
    at emitNone (events.js:85:20)
    at IncomingMessage.emit (events.js:179:7)
    at endReadableNT (_stream_readable.js:906:12)
    at nextTickCallbackWith2Args (node.js:474:9)
    at process._tickDomainCallback (node.js:429:17)
    at process.wrappedFunction (/pipeline/source/node_modules/newrelic/lib/transaction/tracer/index.js:245:51)
    
    opened by maxfrigge 8
  • Unable to test if queue.delayJob has been processed

    Unable to test if queue.delayJob has been processed

    Ironium version: 4.1.3 Test suite: mocha 3.2.0

    Problem: I'm trying to test queue.delayJob processes a job after X amount of delay. I'm using timekeeper to stub Date and Date.now. After invoking queue.delayJob and Ironium.runJobs() in the test suite, these test(s) fail because the job is not processed. Beanstalkd checks the delay of a job against hte system time, but Timekeeper doesn't stub the system time.

    Potential solution(s)?

    • Use another library to stub the system time (eg, ionix) instead of Timekeeper. I started down this path and it was a bit complicated to implement.
    • Set Ironium's delay based on the environment: for example, set it to 1s in test, in dev/prod set to the actual delay time.
    • Create a method in Ironium to inspect the queue, and find the job with the delay in one test. In another test, run the job without delay and check the if the job was processed correctly.
    opened by ugotsoul 6
  • Error queuing to tasks: DRAINING

    Error queuing to tasks: DRAINING

    This is happening running against iron.io.

    I am running on version 3.0.1 but this was happening on 2.7.0 before. Basically the queue doesn't work at all - neither sending nor receiving messages.

    I have also deleted the MQ2 queue to make sure it's not a compatibility issue. First restarted my ironium application and expected it to setup the queue automatically, which didn't work. Then I created the queue by hand, but it didn't work either.

    Here goes the stack:

    Error: Error queuing to tasks: DRAINING
      at Queue._delayJob$ (/pipeline/source/node_modules/ironium/lib/queues.js:549:19)
      at tryCatch (/pipeline/source/node_modules/ironium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
      at GeneratorFunctionPrototype.invoke [as _invoke] (/pipeline/source/node_modules/ironium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
      at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (/pipeline/source/node_modules/ironium/node_modules/babel-runtime/regenerator/runtime.js:100:21)
      at GeneratorFunctionPrototype.invoke (/pipeline/source/node_modules/ironium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
      at run (/pipeline/source/node_modules/ironium/node_modules/babel-runtime/node_modules/core-js/library/modules/es6.promise.js:89:39)
      at /pipeline/source/node_modules/ironium/node_modules/babel-runtime/node_modules/core-js/library/modules/es6.promise.js:100:28
      at flush (/pipeline/source/node_modules/ironium/node_modules/babel-runtime/node_modules/core-js/library/modules/$.microtask.js:17:13)
      at doNTCallback0 (node.js:407:9)
      at process._tickDomainCallback (node.js:377:13)
      at process.wrappedFunction (/pipeline/source/node_modules/newrelic/lib/transaction/tracer/index.js:271:51)
    
    opened by maxfrigge 5
  • Beanstalkd webhook url is localhost only?

    Beanstalkd webhook url is localhost only?

    Looking at the configuration.js, it appears that the assumption is that any webhook usage for beanstalkd would always access localhost. I'm not clear if this is an oversight, or indeed even an issue, but it strikes me as incorrect. Shouldn't the host in the WEBHOOK_LOCAL that's used for beanstalkd config use whatever beanstalkd host is specified?

    Browsing the rest of the codebase it wasn't immediately apparent if the webhook url was actually necessary at all though.

    Would appreciate some guidance on this, even if just to tell me it's really a non-issue :)

    opened by willvincent 4
  • Allow whitelisting of queues to be processed.

    Allow whitelisting of queues to be processed.

    Ironium.configure({
      queues: [ 'foo', 'bar' ]
    });
    

    Or

    env IRONIUM_QUEUES=foo,bar npm run worker
    

    Ironium will process jobs only for the selected queues, allowing for more granular scaling of workloads.

    opened by djanowski 4
  • Scheduled jobs with iron.io don't work properly

    Scheduled jobs with iron.io don't work properly

    I've created a simple worker that uses iron.io as backend:

    var ironium = require('ironium');
    var config = require('./iron.json');
    ironium.configure(config);
    
    ironium.scheduleJob('second', '1s', function(next) {
      console.log('scheduling');
      next();
    });
    
    ironium.start();
    

    but when I run it, scheduling is displayed only once. I see processed message in ironmq, but only one first job is consumed. No next job is scheduled.

    opened by sheerun 4
  • Bulk loading jobs

    Bulk loading jobs

    I'm looking at using Iron.io to do bulk processing for 100s of thousands of micro-jobs. Is there a way to bulk-upload jobs as well as letting a worker grab multiple jobs at a time?

    Nice work on this library btw! Been enjoying poking around your code/docs.

    opened by KyleAMathews 3
  • Is it possible to have multiple workers connect to the same queue?

    Is it possible to have multiple workers connect to the same queue?

    When I run the worker application in a docker container and scale the container to run in let's say 5 instances. Will I be able to process 5 times as many messages from the queue or will each message be processed 5 times?

    opened by maxfrigge 2
  • beanstalkd version?

    beanstalkd version?

    What server version is this tested against? I'm loving the syntax you provide in this library, saves me from wrapping fivebeans on my own, however i keep seeing: beanstalkd: prot.c:710 in check_err: read(): Connection reset by peer

    And i'm wonderinf if there could be a version mismatch error?

    opened by mickhansen 2
  • next param to queueJob doesn't exist

    next param to queueJob doesn't exist

    Hey,

    The readme says:

    customer.on('save', function(next) {
      if (this.isNew)
        sendWelcomeEmail.queueJob(this.id, next);
      else
        next();
    });
    

    but the queueJob signature don't have callback as second param. maybe you forgot to fix docs.

    opened by sheerun 1
Owner
Assaf Arkin
☕️ Need more coffee
Assaf Arkin
Run scheduled tasks

Berkala Berkala runs scheduled tasks specified in a YAML-based configuration. To get started, first download the binary for your operating system from

Ariya Hidayat 31 Aug 12, 2022
A Remix.run stack to monitor your BullMQ queues

Remix Matador stack A bold interface that helps you monitor your BullMQ queues. Learn more about Remix Stacks. $ npx create-remix@latest --template nu

Andrea 19 Dec 15, 2022
Bree is the best job scheduler for Node.js and JavaScript with cron, dates, ms, later, and human-friendly support.

The best job scheduler for Node.js and JavaScript with cron, dates, ms, later, and human-friendly support. Works in Node v10+ and browsers, uses workers to spawn sandboxed processes, and supports async/await, retries, throttling, concurrency, and graceful shutdown. Simple, fast, and lightweight. Made for @ForwardEmail and @ladjs.

Bree - The Best Node.js and JavaScript Job Scheduler 2.5k Dec 30, 2022
A fast, robust and extensible distributed task/job queue for Node.js, powered by Redis.

Conveyor MQ A fast, robust and extensible distributed task/job queue for Node.js, powered by Redis. Introduction Conveyor MQ is a general purpose, dis

Conveyor MQ 45 Dec 15, 2022
Kue is a priority job queue backed by redis, built for node.js.

Kue Kue is no longer maintained Please see e.g. Bull as an alternative. Thank you! Kue is a priority job queue backed by redis, built for node.js. PRO

Automattic 9.4k Dec 20, 2022
A simple, fast, robust job/task queue for Node.js, backed by Redis.

A simple, fast, robust job/task queue for Node.js, backed by Redis. Simple: ~1000 LOC, and minimal dependencies. Fast: maximizes throughput by minimiz

Bee Queue 3.1k Jan 5, 2023
Premium Queue package for handling distributed jobs and messages in NodeJS.

The fastest, most reliable, Redis-based queue for Node. Carefully written for rock solid stability and atomicity. Sponsors · Features · UIs · Install

null 13.5k Dec 31, 2022
Challenge [Frontend Mentor] - In this challenge, JavaScript was used to filter jobs based on the selected categories. Technologies used: HTML5, CSS3 and React.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Rui Neto 11 Apr 13, 2022
Cloud Run Jobs Demos - A collection of samples to show you how and when to run a container to completion without a server

Cloud Run Jobs Demo Applications Cloud Run Jobs allows you to run a container to completion without a server. This repository contains a collection of

Google Cloud Platform 34 Dec 23, 2022
Out of the box modern User Interface, so you can see and manage your Workhorse jobs in realtime

WORKHORSE UI Out of the box modern User Interface, so you can see and manage your Workhorse jobs in realtime. Start local Run npm i Copy and name prox

Workhorse 2 Apr 15, 2022
Nodejs Background jobs using redis.

node-resque: The best background jobs in node. Distributed delayed jobs in nodejs. Resque is a background job system backed by Redis (version 2.6.0 an

Actionhero 1.2k Jan 3, 2023
A simple package for single or batch image download and conversion using node streams.

image-batch-download A simple package for basic image downloading and processing. Supported formats: JPEG PNG WebP Installation With Yarn: yarn add im

Tech Root 777 5 Jan 2, 2022
A simple Node.js APIBAN client for downloading banned IPs and inserting them into a redis set

apiban-redis A simple Node.js APIBAN client for downloading banned IPs and inserting them into a redis set. Installation This utility can be run as a

jambonz 4 Apr 5, 2022
Cache is easy to use data caching Node.js package. It supports Memcached, Redis, and In-Memory caching engines.

Cache Cache NPM implements wrapper over multiple caching engines - Memcached, Redis and In-memory (use with single threaded process in development mod

PLG Works 49 Oct 24, 2022
A simple high-performance Redis message queue for Node.js.

RedisSMQ - Yet another simple Redis message queue A simple high-performance Redis message queue for Node.js. For more details about RedisSMQ design se

null 501 Dec 30, 2022
Lib for work to multiple thread (Node.js)

ad-worker npm i ad-worker This library allows spawn threads and transfer control by name, with an isolated context, or shared data between threads. Ex

Артём Полторацкий 10 Nov 6, 2022
Type-safe and Promisified API for Web Worker and Iframe

?? You can help the author become a full-time open-source maintainer by sponsoring him on GitHub. typed-worker Install npm i typed-worker Usage Create

EGOIST 189 Dec 31, 2022
Redis-backed task queue engine with advanced task control and eventual consistency

idoit Redis-backed task queue engine with advanced task control and eventual consistency. Task grouping, chaining, iterators for huge ranges. Postpone

Nodeca 65 Dec 15, 2022
Build and deploy a roadmap voting app for your porject

Roadmap Voting App You can deploy Roadmap application yourself and get feedback from your users about your roadmap features. See the live example. In

Upstash 91 Jan 3, 2023