nodefase
v0.1.0
Published
Fast Asynchronous MicroService Environment for Node.js, compatible with aiofase
Maintainers
Readme
nodefase
Fast Asynchronous MicroService Environment for Node.js, compatible with aiofase (Python).
Uses ZeroMQ (PUSH/PULL + PUB/SUB) as the communication layer. Services connect to a central broker that relays all messages.
Requirements
- Node.js >= 18
libzmqinstalled on the system
# Ubuntu/Debian
sudo apt install libzmq3-dev
# macOS
brew install zeromqInstallation
npm install nodefaseQuick Start
1. Start the broker
npx nodefase -s tcp://0.0.0.0:3000 -r tcp://0.0.0.0:40002. Create a service
const { MicroService } = require('nodefase')
const sleep = (ms) => new Promise(r => setTimeout(r, ms))
class DatabaseService {
start() {
const ms = new MicroService('tcp://localhost:3000', 'tcp://localhost:4000', 'Database')
ms.on('on_connect', () => console.log('connected'))
ms.on('save_data', async (service, data) => {
console.log(`saving data from ${service}:`, data)
return { status: 'saved' }
})
ms.start()
}
}const { MicroService } = require('nodefase')
const sleep = (ms) => new Promise(r => setTimeout(r, ms))
const sensor = new MicroService('tcp://localhost:3000', 'tcp://localhost:4000', 'Sensor')
sensor.task(async () => {
while (true) {
const result = await sensor.request_action('save_data', { value: 42 })
console.log('result:', result)
await sleep(2000)
}
})
sensor.start()API
new MicroService(senderEndpoint, receiverEndpoint, name [, debug])
| Parameter | Type | Description |
|---|---|---|
| senderEndpoint | string | PUB endpoint of the broker (subscribe) |
| receiverEndpoint | string | PULL endpoint of the broker (push to) |
| name | string | Unique name for this service |
| debug | boolean | Enable verbose logging (default: false) |
ms.on(name, fn)
Registers an action handler or event hook.
// action — called by other services
ms.on('my_action', async (service, data) => {
return { result: 'ok' }
})
// event hooks
ms.on('on_connect', () => { /* connected to broker */ })
ms.on('on_new_service', (service, actions) => { /* another service registered */ })
ms.on('on_broadcast', (service, data) => { /* broadcast received */ })
ms.on('on_response', (service, data) => { /* direct response received */ })ms.task(fn)
Registers a background function that runs when start() is called.
ms.task(async () => {
while (true) {
await doSomething()
await sleep(5000)
}
})ms.start()
Announces the service to the broker and starts all registered tasks.
ms.request_action(action, data [, timeout])
Calls a remote action and returns a Promise that resolves with the return value of the handler.
// fire-and-forget
ms.request_action('save_data', { value: 42 })
// await result
const result = await ms.request_action('save_data', { value: 42 })
// with timeout in seconds — rejects with TimeoutError if no response arrives in time
const result = await ms.request_action('save_data', { value: 42 }, 10)ms.sendBroadcast(data)
Sends a message to all connected services. Triggers on_broadcast on the receivers.
ms.sendBroadcast({ event: 'service_ready' })ms.response(service, data)
Sends a direct response to a service. Triggers on_response on the receiver.
ms.response(service, { status: 'ok' })Server CLI
node server.js [options]
Options:
-s, --sender-endpoint <endpoint> PUB endpoint (default: tcp://0.0.0.0:3000)
-r, --receiver-endpoint <endpoint> PULL endpoint (default: tcp://0.0.0.0:4000)
-d, --debug Enable verbose message logging
-h, --help Display helpThe server can also be used programmatically:
const { Server } = require('nodefase')
const server = new Server('tcp://0.0.0.0:3000', 'tcp://0.0.0.0:4000', true)Message Protocol
| Prefix | Description |
|---|---|
| <r>: | Service registration — announces name and available actions |
| <b>: | Broadcast — delivered to all services |
| <ares>: | Async response — resolves a pending request_action Promise |
| {action}: | Action call — dispatched to the matching handler |
| {service}: | Direct response — triggers on_response on the target service |
Architecture
MicroService A ──PUSH──▶ Server (PULL/PUB) ──PUB──▶ MicroService A
MicroService B ──PUSH──▶ ──PUB──▶ MicroService BThe server is a stateless relay — it does not interpret messages.
Any language with a ZeroMQ binding can participate in the same network.
Examples
# terminal 1 — broker
node server.js -d
# terminal 2 — database service
node examples/database/database.js
# terminal 3 — sensor
node examples/database/sensor.jsSee examples/timeout for remote exceptions and timeout handling.
Compatibility
The protocol is identical to aiofase (Python), allowing Python and Node.js services to communicate on the same broker.
License
MIT
