The invoker based on event model provides an elegant way to call your methods in another container via promisify functions

Overview

event-invoke

NPM version build status Test coverage npm download

The invoker based on event model provides an elegant way to call your methods in another container via promisify functions. (like child-processes, iframe, web worker etc). (Inspired by node-ipc-call)

825cb24fe4bb2cc7f9713606d8594a77

Usage

  • Install the package
$ npm i -S event-invoke

Invoking method via child process

// parent.js
const cp = require('child_process');
const { Invoker } = require('event-invoke');

const invokerChannel = cp.fork('./child.js');

const invoker = new Invoker(invokerChannel);

async function main() {
  const res1 = await invoker.invoke('sleep', 1000);
  console.log('sleep 1000ms:', res1);
  const res2 = await invoker.invoke('max', [1, 2, 3]); // 3
  console.log('max(1, 2, 3):', res2);
  invoker.destroy();
}

main();
// child.js
const { Callee } = require('event-invoke');

const calleeChannel = process;

const callee = new Callee(calleeChannel);

// async method
callee.register(async function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
});

// sync method
callee.register(function max(...args) {
  return Math.max(...args);
});

callee.listen();

Invoking method via child process via custom channel

// pm2.config.cjs
module.exports = {
  apps: [
    {
      script: 'invoker.js',
      name: 'invoker',
      exec_mode: 'fork',
    },
    {
      script: 'callee.js',
      name: 'callee',
      exec_mode: 'fork',
    }
  ],
};
// callee.js
import net from 'net';
import pm2 from 'pm2';
import {
  Callee,
  BaseCalleeChannel
} from 'event-invoke';

const messageType = 'event-invoke';
const messageTopic = 'some topic';

class CalleeChannel extends BaseCalleeChannel {
  constructor() {
    super();
    this._onProcessMessage = this.onProcessMessage.bind(this);
    process.on('message', this._onProcessMessage);
  }

  onProcessMessage(packet) {
    if (packet.type !== messageType) {
      return;
    }
    this.emit('message', packet.data);
  }

  send(data) {
    pm2.list((err, processes) => {
      if (err) { throw err; }
      const list = processes.filter(p => p.name === 'invoker');
      const pmId = list[0].pm2_env.pm_id;
      pm2.sendDataToProcessId({
        id: pmId,
        type: messageType,
        topic: messageTopic,
        data,
      }, function (err, res) {
        if (err) { throw err; }
      });
    });
  }

  destroy() {
    process.off('message', this._onProcessMessage);
  }
}

const channel = new CalleeChannel();
const callee = new Callee(channel);

// async method
callee.register(async function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
});

// sync method
callee.register(function max(...args) {
  return Math.max(...args);
});

callee.listen();

// keep your process alive
net.createServer().listen();
// invoker.js
import pm2 from 'pm2';
import {
  Invoker,
  BaseInvokerChannel
} from 'event-invoke';

const messageType = 'event-invoke';
const messageTopic = 'some topic';

class InvokerChannel extends BaseInvokerChannel {
  constructor() {
    super();
    this._onProcessMessage = this.onProcessMessage.bind(this);
    process.on('message', this._onProcessMessage);
  }

  onProcessMessage(packet) {
    if (packet.type !== messageType) {
      return;
    }
    this.emit('message', packet.data);
  }

  send(data) {
    pm2.list((err, processes) => {
      if (err) { throw err; }
      const list = processes.filter(p => p.name === 'callee');
      const pmId = list[0].pm2_env.pm_id;
      pm2.sendDataToProcessId({
        id: pmId,
        type: messageType,
        topic: messageTopic,
        data,
      }, function (err, res) {
        if (err) { throw err; }
      });
    });
  }

  connect() {
    this.connected = true;
  }

  disconnect() {
    this.connected = false;
  }

  destroy() {
    process.off('message', this._onProcessMessage);
  }
}

const channel = new InvokerChannel();
channel.connect();

const invoker = new Invoker(channel);

setInterval(async () => {
  const res1 = await invoker.invoke('sleep', 1000);
  console.log('sleep 1000ms:', res1);
  const res2 = await invoker.invoke('max', [1, 2, 3]); // 3
  console.log('max(1, 2, 3):', res2);
}, 5 * 1000);

Web worker

TODO

Iframe

TODO

Browser page

TODO

License

MIT

You might also like...

Transmute one JavaScript string into another by way of mutating its AST. Powered by babel and recast.

equivalent-exchange Transmute one JavaScript string into another by way of mutating its AST. Powered by babel and recast. Features Can parse code usin

Jul 9, 2022

Decorator-based service container for TypeScript

Capsule Lightweight TypeScript service container. Note: This is just quick preview of the documentation, not even alpha quality. For more detailed stu

Sep 26, 2022

Easiest 1-click way to install and use Stable Diffusion on your own computer. Provides a browser UI for generating images from text prompts and images. Just enter your text prompt, and see the generated image.

Easiest 1-click way to install and use Stable Diffusion on your own computer. Provides a browser UI for generating images from text prompts and images. Just enter your text prompt, and see the generated image.

Stable Diffusion UI Easiest way to install and use Stable Diffusion on your own computer. No dependencies or technical knowledge required. 1-click ins

Dec 30, 2022

Functions Recipes is a library of examples to help you getting started with Salesforce Functions and get used to their main features.

Functions Recipes is a library of examples to help you getting started with Salesforce Functions and get used to their main features.

Functions Recipes Introduction Salesforce Functions lets you use the Salesforce Platform for building event-driven, elastically scalable apps and expe

Dec 29, 2022

đŸĻĢ A simple way to implement event sourcing in TypeScript

✨ Better DevX for Event Sourcing in TypeScript Castore provides a unified interface for implementing Event Sourcing in TypeScript. Define your events

Nov 18, 2022

Leader Board is a simple project based on JavaScript programing language. The purpose of this project is to work with APIs and ASYNC & AWAIT methods. I have used vanilla JavaScript with web pack to implement this project

Leader Board is a simple project based on JavaScript programing language. The purpose of this project is to work with APIs and ASYNC & AWAIT methods. I have used vanilla JavaScript with web pack to implement this project

Leader Board - JavaScript Project Table of contents Overview The challenge Screenshot Links Project Setup commands My process Built with What I learne

Oct 21, 2022

Network physical synchronization model room based on babylonjs + ammojs

Network physical synchronization model room based on babylonjs + ammojs

Network physical synchronization model room based on babylonjs + ammojs The red mesh calculates the physical effects locally of the current user, and

Nov 19, 2022

This repository contains a fullstack chatbot project based on the ChatGPT `gpt-3.5-turbo` model.

This is a fullstack chatbot created with React, Nodejs, OpenAi, and ChatGPT while developing the following tutorial: How To Build A Chat Bot Applicati

May 10, 2023

Catalogist is the easy way to catalog and make your software and (micro)services visible to your organization in a lightweight and developer-friendly way.

Catalogist is the easy way to catalog and make your software and (micro)services visible to your organization in a lightweight and developer-friendly way.

catalogist 📚 📓 📒 📖 🔖 The easy way to catalog and make your software and (micro)services visible to your organization through an API You were a pe

Dec 13, 2022
Owner
尚挚
Software developer
尚挚
Public repository of assets used during editions of AWS LATAM Container Roadshow event.

LATAM Containers Roadshow This is the official repository of assets related to LATAM Containers Roadshow, an all-day customer-facing event to highligh

AWS Samples 12 Dec 6, 2022
fcall, fetch and call any remote hot functions, anywhere, anytime, without installations or configurations.

fcall, fetch and call any remote hot functions, anywhere, anytime, without installations or configurations.

įĢ‹å…š Lidang 4 Sep 20, 2022
⚡🚀 Call multiple view functions, from multiple Smart Contracts, in a single RPC query!

ethers-multicall ⚡ ?? Call multiple view functions, from multiple Smart Contracts, in a single RPC query! Querying an RPC endpoint can be very costly

Morpho Labs 20 Dec 30, 2022
A set of useful helper methods for writing functions to handle Cloudflare Pub/Sub messages (https://developers.cloudflare.com/pub-sub/)

pubsub A set of useful helper methods for writing functions to handle Cloudflare Pub/Sub messages. This includes: A isValidBrokerRequest helper for au

Cloudflare 18 Dec 4, 2022
A collection of functions and methods to make it easier for you to create applications.

def-helper A collection of functions and methods to make it easier for you to create applications. Install npm install --save def-helper Usage import

Dede Fuji Abdul 2 Oct 13, 2022
Provides simple and the most useful methods to string operations in JavaScript / Node.js

?? Strops (String Operations) Provides simple methods for the most useful operations with substrings: - remove, replace, get from A to B, get from A t

Max Shane 3 May 20, 2022
The Easel Javascript library provides a full, hierarchical display list, a core interaction model, and helper classes to make working with the HTML5 Canvas element much easier.

EaselJS EaselJS is a library for building high-performance interactive 2D content in HTML5. It provides a feature-rich display list to allow you to ma

CreateJS 8k Dec 29, 2022
'event-driven' library aims to simplify building backends in an event driven style

'event-driven' library aims to simplify building backends in an event driven style(event driven architecture). For message broker, light weight Redis Stream is used and for event store, the well known NoSQL database, MongoDB, is used.

Sihoon Kim 11 Jan 4, 2023
Provides event handling and an HTMLElement mixin for Declarative Shadow DOM in Hotwire Turbo.

Turbo Shadow Provides event handling and an HTMLElement mixin for Declarative Shadow DOM support in Hotwire Turbo. Requires Turbo 7.2 or higher. Quick

Whitefusion 17 Sep 28, 2022