Global Event with…. Global Events

Global Event with…. Global Events

I am currently working on a personal project, one about which I may reveal more in the future. For this project I needed a simple way of communicating between processes. In my case, these processes are created ad-hoc, so I didn’t want to have to keep track of said processes, as I viewed this as being error-prone.

In the past I wrote redis-streams-manager,which patches node’s EventEmitter to manage reading from multiple streams. This setup was what I wanted this time; only the EventEmitter native interface, with the specifics buried below. I wanted to be able to emit an event from one process, which will then be received by all listeners, including in other processes. Because I didn’t need the extra features streams offer, I decided to use the publish/subscribe mechanism instead.

The idea worked. My project had global events. Since it’s a relatively self-contained module, I decided to extract and publish it. The result is Global Events, which does exactly what it sounds like. It even uses msgpackr to serialize and de-serialize an optional data payload.

Global Events has the same interface as redis-streams-manager, and both can be used to achieve the same thing. The APIs of both are as close to the original EventEmitter API as possible, with only slight additions or improvements.

So you want an example:

import IORedis from "ioredis";
import GlobalEvents from "@art-of-coding/global-events";

// Create a non-dedicated connection
// You can use this connection elsewhere
const connection = new IORedis();

const events = new GlobalEvents({
  // Set the Redis connection
  // This connection is duplicated internally to act as subscriber
  connection,
  // An optional prefix
  prefix: "prefix:",
  // Optional msgpackr configuration
  // See https://github.com/kriszyp/msgpackr#options
  msgpackr: { useRecords: true },
});

// Listen for an event
// Will automatically subscribe to the event if no subscription is open yet
events.on("expected-event", (data: MyDataInterface) => {
  // `data` is the event data if the event had a data payload
});

// Emit an event
events.emit("some-event");

// Emit an async event
await events.emitAsync("async-event");

// Emit an event with some data
events.emit("another-event", { some: "data" });

// Disconnect the subscriber
// After calling this the instance is no longer usable
await events.disconnect();

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.