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

rinvoke

v1.1.0

Published

RPC library based on net sockets, can work both with tcp sockets and ipc

Downloads

7

Readme

rinvoke

js-standard-style Build Status Coverage Status

Build your distributed functions system with Rinvoke!
Rinvoke is a RPC library based on net sockets, can work both with tcp sockets and ipc.
It has built in reconnect logic and supports multiple parser/serializers, such as msgpack or protbuf.
Internally uses tentacoli to multiplex the requests and avvio to guarantee the asynchronous bootstrap of the application, it also provide an handy request validation out of the box with JSON schema.

Install

npm i rinvoke --save

Usage

Rinvoke could be used as a server or client, so when your require it you must specify it.
Let's see an example for the server:

const rinvoke = require('rinvoke/server')()

rinvoke.register('concat', (req, reply) => {
  reply(null, req.a + req.b)
})

rinvoke.listen(3000, err => {
  if (err) throw err
})

And now for the client:

const rinvoke = require('rinvoke/client')({
  port: 3000
})

rinvoke.invoke({
  procedure: 'concat',
  a: 'hello ',
  b: 'world'
}, (err, result) => {
  if (err) {
    console.log(err)
    return
  }
  console.log(result)
})

The client could seem synchronous but internally everything is handled asynchronously with events.
Checkout the examples folder if you want to see more examples!

API

Server

server([opts])

Instance a new server, the options object can accept a custom parser/serializer via the codec field.

const rinvoke = require('rinvoke/server')({
  codec: {
    encode: JSON.stringify,
    decode: JSON.parse
  }
})

The default codec is JSON.
Events:

  • 'connection'
  • 'error'
  • 'request'
  • 'listening'

register(procedureName, [schema,] procedureFunction)

Registers a new procedure, the name of the procedure must be a string, the function has the following signature: (request, reply) where request is the request object and reply a function t send the response back to the client.

rinvoke.register('concat', (req, reply) => {
  reply(null, req.a + req.b)
})

Promises and async/await are supported as well!

rinvoke.register('concat', async req => {
  return req.a + req.b
})

Validation

Rinvoke offers you out of the box a nice and standard way to validate your requests, JSON schema!
Internally uses ajv to achieve the maximum speed and correctness.

rinvoke.register('concat', {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' }
  },
  required: ['a', 'b']
}, (req, reply) => {
  reply(null, req.a + req.b)
})

listen(portOrPath, [address], callback)

Run the server over the specified port (and address, default to 127.0.0.1), if you specify a path (as a string) it will use the system socket to perform ipc.

rinvoke.listen(3000, err => {
  if (err) throw err
})

rinvoke.listen(3000, '127.0.0.1', err => {
  if (err) throw err
})

rinvoke.listen('/tmp/socket.sock', err => {
  if (err) throw err
})

Client

client(options)

Instance a new client, the options object must contain a port or path field, furthermore can accept a custom parser/serializer via the codec field. If you want to activate the automatic reconnection handling pass reconnect: true (3 attempts with 1s timeout), if you want to configure the timeout handling pass an object like the following:

const rinvoke = require('rinvoke/client')({
  port: 3000,
  address: '127.0.0.1'
  reconnect: {
    attempts: 5,
    timeout: 2000
  },
  codec: {
    encode: JSON.stringify,
    decode: JSON.parse
  }
})

The default codec is JSON.
Events:

  • 'connect'
  • 'error'
  • 'close'
  • 'timeout'

invoke(request, callback)

Invoke a procedure on the server, the request object must contain the key procedure with the name of the function to call.
The callback is a function with the following signature: (error, response).

rinvoke.invoke({
  procedure: 'concat',
  a: 'hello ',
  b: 'world'
}, (err, result) => {
  if (err) {
    console.log(err)
    return
  }
  console.log(result)
})

Promises are supported as well!

rinvoke
  .invoke({
    procedure: 'concat',
    a: 'a',
    b: 'b'
  })
  .then(console.log)
  .catch(console.log)

fire(request [, callback])

Fire (and forget) a procedure on the server, the request object must contain the key procedure with the name of the function to call.
The optional callback will be called if there is an error while sending the message, or after the message has been sent successfully.

rinvoke.fire({
  procedure: 'concat',
  a: 'hello ',
  b: 'world'
})

timeout(time)

Sets the timeout of the socket.

keepAlive(bool)

Sets the keep-alive property.

Method for both client and server

use(callback)

The callback is a function witb the following signature: instance, options, next.
Where instance is the client instance, options, is an options object and next a function you must call when your code is ready.
This api is useful if you need to load an utility, a database connection for example. use will guarantee the load order an that your client/server will boot up once every use has completed.

rinvoke.use((instance, opts, next) => {
  dbClient.connect(opts.url, (err, conn) => {
    instance.db = conn // now you can access in your function the database connection with `this.db`
    next()
  })
})

onClose(callback)

Hook that will be called once you fire the close callback.

rinvoke.onClose((instance, done) => {
  // do something
  done()
})

close(callback)

Once you call this function the socket server and client will close and all the registered functions with onClose will be called.

rinvoke.close((err, instance, done) => {
  // do something
  done()
})

CLI

You can even run the server with the integrated cli! In your package.json add:

{
  "scripts": {
    "start": "rinvoke server.js"
  }
}

And then create your server file:

module.exports = async req => `Hello ${req.name}!`

You can also use an extended version of the above example:

function sayHello (rinvoke, opts, next) {
  rinvoke.register('hello', (req, reply) => {
    reply(null, { hello: 'world' })
  })

  next()
}

module.exports = sayHello

The options of the cli are:

--port       -p      # default 3000
--address    -a      # default 127.0.0.1
--path       -P      # path of the ipc web socket
--name       -n      # name of your exported function

Acknowledgements

This project is kindly sponsored by LetzDoIt.

License

MIT

Copyright © 2017 Tomas Della Vedova