Skip to content

Commit

Permalink
update readme with latest enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Coulon authored and nicocoul committed Nov 30, 2021
1 parent b2d7d1f commit 5369c60
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 88 deletions.
149 changes: 77 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# ya-rfc
[![npm version](https://badge.fury.io/js/ya-rfc.svg)](http://badge.fury.io/js/ya-rfc) [![license](https://img.shields.io/npm/l/ya-rfc.svg)](http://badge.fury.io/js/ya-rfc) [![test](https://github.com/nicocoul/ya-rfc/actions/workflows/test.yml/badge.svg)](https://github.com/nicocoul/ya-rfc/actions/workflows/test.yml) [![Coverage Status](https://coveralls.io/repos/github/nicocoul/ya-rfc/badge.svg?branch=main)](https://coveralls.io/github/nicocoul/ya-rfc?branch=main) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/nicocoul/ya-rfc.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/nicocoul/ya-rfc/context:javascript)

Yet Another [Remote Function Call](https://en.wikipedia.org/wiki/Remote_procedure_call) library for Node js.

Ya-rpc anables to run functions on remote machines within a distributed system without worrying about network messaging & load balancing.
Expand All @@ -8,21 +9,48 @@ It provides an easy way to implement performance-critical applications by parall

![basic execution flow](https://github.com/nicocoul/ya-rfc/blob/dev/img/arch.png)

### Key Features
## Key Features
* multiple transports available
* websocket
* tcp
* ipc
* blazing fast
* integrates well with [ya-pubsub](https://www.npmjs.com/package/ya-pubsub)
* asynchronous
* embeddable

### Function execution flow
### Typical execution flow
![basic execution flow](https://github.com/nicocoul/ya-rfc/blob/dev/img/basicExecFlow.png)

### Example
Given a module accessible by the RFC server
## Installation
```sh
$ npm install ya-rfc
```
**ya-rfc** is tested with versions 12, 14 & 16 on of node.js on ubuntu-latest.

## Quick start
```javascript
// procedures.js
const ya = require('ya-rfc');
```
### Broker
Create a **rfc** broker that accepts **TCP**, **IPC** and **websocket** connections (only one transport required)
``` javascript
const namedPipe = path.join('\\\\.\\pipe', 'some-pipe');

ya.broker([
ya.transports.ipc(namedPipe),
ya.transports.tcp(8005, 'localhost'),
ya.transports.ws(8006, 'localhost')]);
```

### Server
Define functions that remote **rfc** clients will request to execute
``` javascript
// procedures.js
module.exports = {
sum: (a, b) => {
return a + b
},
count: (until, progress) => {
const x = parseInt(until / 10)
for (let i = 0; i < until; i++) {
Expand All @@ -32,44 +60,54 @@ module.exports = {
}
return until
}
}
};
```
Create a (ideally multiple) **rfc** server that connects to the Broker over **TCP**, it can also be **IPC** or **websocket**
``` javascript
ya.server(ya.transports.tcp(8005, 'localhost'), 'procedures.js');

// ya.server(ya.transports.ws(8006, 'localhost'));

// const win32namedPipe = require('path').join('\\\\.\\pipe', 'some-pipe');
// ya.server(ya.transports.ipc(win32namedPipe));
```
function 'count' can be executed remotely over tcp
```javascript
const net = require('net')
const path = require('path')
const ya = require('../index.js')

// Create broker a that forwards requests to servers
// according to their CPU and memory usage.
const broker = ya.broker()
broker.plug(ya.plugins.net(net.Server().listen(8002)))

// Create servers that spawns worker processes at startup.
// Round-robin scheduling is used to balance load over worker processes.
const modulePath = path.join(__dirname, 'procedures.js')
ya.server.net({ host: 'localhost', port: 8002 }, modulePath)
ya.server.net({ host: 'localhost', port: 8002 }, modulePath)

const client = ya.client.net({ host: 'localhost', port: 8002 })
// execute function 'count' from a remote client
client.execute('count', [10000], (err, data) => {
if (!err) {
console.log('result is', data)
}
}, {
### Client
Create a **rfc** client that connects to the Broker over **TCP**, it can also be **IPC** or **websocket**
``` javascript
const client = ya.client(ya.transports.tcp(8005, 'localhost'));

// const wsClient = ya.client(ya.transports.ws(8006, 'localhost'))

// const win32namedPipe = require('path').join('\\\\.\\pipe', 'some-pipe')
// const ipcClient = ya.client(ya.transports.ipc(win32namedPipe))
```
Execute a function remotely
``` javascript
tcpClient.remote.sum(1, 2)
.then(result => {
console.log(result)
})
.catch(error => {
console.error(error)
});
/* output:
3
*/
```
Execute a function remotely and get notified of its progression
``` javascript
client.remote.count(10000, {
onProgress: (progress) => {
console.log('progress', progress)
},
onStatus: (status) => {
console.log('status', status)
}
})

.then(result => {
console.log('result is', result)
})
.catch(error => {
console.error(error)
});
/* output:
status scheduled
status started
progress 0/10000
progress 1000/10000
progress 2000/10000
Expand All @@ -80,45 +118,12 @@ progress 6000/10000
progress 7000/10000
progress 8000/10000
progress 9000/10000
status end
result is 10000
*/

```
or over websockets
```javascript
const { WebSocketServer } = require('ws')
const path = require('path')
const ya = require('../index.js')

const broker = ya.broker()
broker.plug(ya.plugins.ws(new WebSocketServer({ port: 8004 })))

const modulePath = path.join(__dirname, 'procedures.js')
ya.server.ws({ host: 'localhost', port: 8004 }, modulePath)

const rpcClient = ya.client.ws({ host: 'localhost', port: 8004 })
// execute procedure count from the client
// rpcClient.execute('count', [10000], (err, data) => {
// if (!err) {
// console.log(data)
// }
// })

rpcClient.remote.count(100, { onProgress: console.log, onStatus: console.log })
.then(result => {
console.log(result)
})
.catch(error => {
console.error(error)
})

/* output:
10000
*/

```

## Versioning

Yaps-node uses [Semantic Versioning](http://semver.org/) for predictable versioning.

## License
This library is licensed under MIT.
20 changes: 10 additions & 10 deletions cli/render-readme.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs')
const path = require('path')
const mustache = require('mustache')
// const mustache = require('mustache')

const https = require('https')

Expand All @@ -19,19 +19,19 @@ function convert (mermaidPath, pngPath) {

console.log(encodeURIComponent('test?'))

// examples
const examples = {
procedures: fs.readFileSync(path.join(__dirname, '..', 'examples', 'procedures.js'), { encoding: 'utf8' }),
tcp: fs.readFileSync(path.join(__dirname, '..', 'examples', 'rpc-tcp.js'), { encoding: 'utf8' }),
ws: fs.readFileSync(path.join(__dirname, '..', 'examples', 'rpc-ws.js'), { encoding: 'utf8' })
}
// // examples
// const examples = {
// procedures: fs.readFileSync(path.join(__dirname, '..', 'examples', 'procedures.js'), { encoding: 'utf8' }),
// tcp: fs.readFileSync(path.join(__dirname, '..', 'examples', 'rpc-tcp.js'), { encoding: 'utf8' }),
// ws: fs.readFileSync(path.join(__dirname, '..', 'examples', 'rpc-ws.js'), { encoding: 'utf8' })
// }

const mrdPath = path.join(__dirname, '..', 'mrd')
const imgPath = path.join(__dirname, '..', 'img')
fs.readdirSync(mrdPath).forEach(entry => {
convert(path.join(mrdPath, entry), path.join(imgPath, `${path.parse(entry).name}.png`))
})

const template = fs.readFileSync(path.join(__dirname, 'README.md.tpl'), { encoding: 'utf8' })
const result = mustache.render(template, { examples })
fs.writeFileSync(path.join(__dirname, '..', 'README.md'), result, { encoding: 'utf8' })
// const template = fs.readFileSync(path.join(__dirname, 'README.md.tpl'), { encoding: 'utf8' })
// const result = mustache.render(template, { examples })
// fs.writeFileSync(path.join(__dirname, '..', 'README.md'), result, { encoding: 'utf8' })
8 changes: 4 additions & 4 deletions mrd/arch.mrd
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ flowchart LR
c1[client1]
c2[client2]
b[broker]
c1-- TCP/WS ---b
c2-- TCP/WS ---b
b-- TCP/WS ---s1m
b-- TCP/WS ---s2m
c1-- TCP/WS/IPC ---b
c2-- TCP/WS/IPC ---b
b-- TCP/WS/IPC ---s1m
b-- TCP/WS/IPC ---s2m
subgraph s1[server1]
s1m
s1m-- IPC ---s1w1
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ya-rfc",
"version": "1.0.0",
"version": "1.1.0",
"description": "Yet Another Remote Function Call library for Node js",
"main": "index.js",
"author": "Nicolas Coulon <coulon_nicolas@hotmail.com> (https://github.com/nicocoul)",
Expand Down

0 comments on commit 5369c60

Please sign in to comment.