hemerajs / hemera Goto Github PK
View Code? Open in Web Editor NEW🔬 Writing reliable & fault-tolerant microservices in Node.js https://hemerajs.github.io/hemera/
License: MIT License
🔬 Writing reliable & fault-tolerant microservices in Node.js https://hemerajs.github.io/hemera/
License: MIT License
log
missing in Hemera types although it exists.
no error
error TS2339: Property 'log' does not exist on type 'Hemera'.
@types/nats-hemera
I cannot get any idea of what this error could be, can someone please point out what is the reason for it
Hapi Javascript Route plugin, I am using hapi-hemera plugin
'use strict';
const Joi = require('joi');
const Boom = require('boom');
const signupHandler = (request, reply) => {
return reply.act({ topic: 'signup', cmd: 'register' },
function (err, result) {
return reply(err || result)
})
};
const _routeConfig = {
description: 'New xyz account signup.',
notes: 'New xyz account signup.',
tags: ['api', 'greeting'],
validate: {
payload: {
company_name: Joi.string().required(),
email: Joi.string().required(),
first_name: Joi.string().required(),
last_name: Joi.string().required(),
mobile: Joi.string().required(),
address: Joi.object({
street: Joi.string().required(),
city: Joi.string().required(),
state: Joi.string().required(),
zip: Joi.string().required(),
country: Joi.string().required()
}),
coordinates: Joi.array().items(Joi.number().required(), Joi.number().required())
.required()
},
headers: Joi.object({
}).unknown()
},
pre: [],
handler: signupHandler,
auth: {
strategy: 'auth0-xyz',
mode: 'required'
},
plugins: {
'hapi-swagger': {
responses: {
'200': {
'description': 'Successfully completed signup process.'
},
'503': {
'description': 'Error occured during signup process.'
}
}
}
}
};
module.exports = {
routeConfig: _routeConfig
};
Worker Process Typescript module
import * as Hemera from 'nats-hemera'
import { Client, connect } from 'nats'
const authUrl = 'nats://localhost:4222'
const nats = connect(authUrl)
const hemera = new Hemera(nats, { logLevel: 'info' })
hemera.ready(() => {
console.log('Ready to listen .. ')
hemera.add({ topic: 'signup', cmd: 'register' }, (req: any, cb: any) => {
console.log(JSON.stringify(req, null, 4))
cb(null, 'req successful')
})
})
export { hemera, nats, authUrl }
I am getting the following error
On Hapi Route
[2017-03-06T02:21:52.608Z] INFO (app/4624 on Mac-Pro.local): Connected!
Plugin registration and server initialization
✔ 5) should be successful (0 ms)
Signup Route
✔ 6) should be registered (6 ms)
[2017-03-06T02:21:52.645Z] INFO (app/4624 on Mac-Pro.local): ACT_OUTBOUND - ID:59507afe9e852550836ad49e070e50ca
[2017-03-06T02:21:52.661Z] INFO (app/4624 on Mac-Pro.local): ACT_INBOUND - ID:undefined (NaNms)
[2017-03-06T02:21:52.664Z] FATAL (app/4624 on Mac-Pro.local): Fatal error
FatalError
at self.sendRequest (/api-modules/signup/node_modules/nats-hemera/build/index.js:777:23)
at Object.callback (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:1133:5)
at Client.processMsg (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:892:11)
at Client.processInbound (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:824:14)
at Socket.<anonymous> (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:421:12)
at emitOne (events.js:96:13)
at Socket.emit (events.js:189:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:551:20)
Cause: SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at Object.exports.parse (/api-modules/signup/node_modules/errio/index.js:191:34)
at Hemera.<anonymous> (/api-modules/signup/node_modules/nats-hemera/build/index.js:762:35)
at done (/api-modules/signup/node_modules/items/lib/index.js:31:25)
at Hemera.<anonymous> (/api-modules/signup/node_modules/nats-hemera/build/index.js:173:7)
at each (/api-modules/signup/node_modules/nats-hemera/build/ext.js:51:11)
at iterate (/api-modules/signup/node_modules/items/lib/index.js:36:13)
at Object.exports.serial (/api-modules/signup/node_modules/items/lib/index.js:39:9)
at Ext.invoke (/api-modules/signup/node_modules/nats-hemera/build/ext.js:54:11)
at self.sendRequest (/api-modules/signup/node_modules/nats-hemera/build/index.js:741:48)
at Object.callback (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:1133:5)
at Client.processMsg (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:892:11)
at Client.processInbound (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:824:14)
at Socket.<anonymous> (/api-modules/signup/node_modules/hapi-hemera/node_modules/nats/lib/nats.js:421:12)
at emitOne (events.js:96:13)
at Socket.emit (events.js:189:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:551:20)
On Worker process
[2017-03-06T02:21:34.659Z] INFO (hemera-f1fa6cc7ea3438aa/4492 on Mac-Pro.local): Connected!
Ready to listen ..
[2017-03-06T02:21:34.670Z] INFO (hemera-f1fa6cc7ea3438aa/4492 on Mac-Pro.local): ADD - ADDED
[2017-03-06T02:21:52.656Z] ERROR (hemera-f1fa6cc7ea3438aa/4492 on Mac-Pro.local): Bad implementation
ImplementationError
at Hemera.onServerPreHandler (/worker-modules/signup/node_modules/nats-hemera/build/index.js:670:34)
at done (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:113:17)
at Hemera.onServerPreHandler (/worker-modules/signup/node_modules/nats-hemera/build/extensions.js:129:3)
at each (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:75:16)
at iterate (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:118:11)
at Function.serial (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:121:9)
at Extension.invoke (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:81:17)
at Hemera.onServerPreRequestHandler (/worker-modules/signup/node_modules/nats-hemera/build/index.js:711:47)
at done (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:113:17)
at Hemera.onServerPreRequest (/worker-modules/signup/node_modules/nats-hemera/build/extensions.js:121:3)
Cause: TypeError: Cannot read property 'type' of undefined
at /worker-modules/signup/node_modules/nats-hemera/build/index.js:661:46
at Function.serial (/worker-modules/signup/node_modules/nats-hemera/build/util.js:69:9)
at Hemera.onServerPreHandler (/worker-modules/signup/node_modules/nats-hemera/build/index.js:648:26)
at done (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:113:17)
at Hemera.onServerPreHandler (/worker-modules/signup/node_modules/nats-hemera/build/extensions.js:129:3)
at each (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:75:16)
at iterate (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:118:11)
at Function.serial (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:121:9)
at Extension.invoke (/worker-modules/signup/node_modules/nats-hemera/build/extension.js:81:17)
at Hemera.onServerPreRequestHandler (/worker-modules/signup/node_modules/nats-hemera/build/index.js:711:47)
[2017-03-06T02:21:52.663Z] FATAL (hemera-f1fa6cc7ea3438aa/4492 on Mac-Pro.local): process exited
Some people have the requirement to access multiple databases with e.g mongo-store
.
With the current solution, we can't provide it because we have to manage the connection by ourselves. There are many drivers which provide it out of the box but some don't.
Proposal:
We using the database name as a suffix for the topic name. This has the benefit that any service with a different database will create a new connection and act as a separate service in Hemera. You also can access the database with different db credentials. By the nature of NATS all requests are load balanced.
This is no replacement for a connection pool which managed the resources more intelligently.
// default
act({
topic: 'mongo-store',
cmd: 'find'
}, ...)
// with specific database
act({
topic: 'mongo-store.db1',
cmd: 'find'
}, ...)
The plugin registration should look like this
// default
hemera.use(hemeraMongo, {
mongo: {
url: 'mongodb://localhost:27017/db'
}
})
// with specific database
hemera.use(hemeraMongo, {
useDbAsTopicSuffix: true,
database: 'db1',
mongo: {
url: 'mongodb://localhost:27017/db'
}
})
I need a really high version of node to be able to use hemera-web.
hemera-web starts to wok with node 7.6.0
Before that I get an error.
const nats = require('nats').connect()
const hemeraWeb = require('hemera-web')
const hemera = new Hemera(nats)
hemera.use(hemeraWeb, {
port: 3000,
host: '127.0.0.1',
pattern: {} // default pattern
})
hemera.ready(() => {
hemera.add({
topic: 'math',
cmd: 'add'
}, (req, cb) => {
cb(null, req.a + req.b)
})
})
Having the nodejs script executing
Get an error with the async keyword (I think):
╰─$ node -v
v6.5.0
╭─romuald@C02M2HBKFD57 ~/Documents/devserver/workspace/hemera-playground/microservices-example ‹2.2.5›
╰─$ node products/index.js
/Users/romuald/Documents/devserver/workspace/hemera-playground/microservices-example/node_modules/hemera-web/lib/index.js:35
this._server = Micro(async (req, res) => {
^
SyntaxError: Unexpected token (
at Object.exports.runInThisContext (vm.js:76:16)
at Module._compile (module.js:528:28)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.require (module.js:483:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/Users/romuald/Documents/devserver/workspace/hemera-playground/microservices-example/node_modules/hemera-web/index.js:3:13)
at Module._compile (module.js:556:32)
According to the docs, we can publish to many subscriber, or publish to only one queue group, but, how to publish to many queue group?
In other word, there are many roles listen to the same topic and react differently, but we wish to clustering a role with many instances, so, a publication should be pushed to all the subscriber roles, but only one instance of each role will receive it.
when i'm run: node web.js in examples.
[2017-05-12T06:43:49.141Z] ERROR (hemera-f09583d25d6f5b4d/21188 on yaochen): No topic to request
HemeraError
at Hemera.act (G:\source\node\微服务\hemera\packages\hemera\lib\index.js:893:19)
at _server.Micro (G:\source\node\微服务\hemera\packages\hemera-web\lib\index.js:71:27)
at resolve (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\micro\lib\server.js:24:34)
at Promise._execute (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\bluebird\js\release\debuggability.js:300:9)
at Promise._resolveFromExecutor (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\bluebird\js\release\promise.js:483:18)
at new Promise (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\bluebird\js\release\promise.js:79:10)
at Function.exports.run (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\micro\lib\server.js:24:3)
at Server.server (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\micro\lib\server.js:13:50)
at emitTwo (events.js:106:13)
at Server.emit (events.js:194:7)
at parserOnIncoming (_http_server.js:563:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
HemeraError
at Hemera.act (G:\source\node\微服务\hemera\packages\hemera\lib\index.js:893:19)
at _server.Micro (G:\source\node\微服务\hemera\packages\hemera-web\lib\index.js:71:27)
at resolve (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\micro\lib\server.js:24:34)
at Promise._execute (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\bluebird\js\release\debuggability.js:300:9)
at Promise._resolveFromExecutor (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\bluebird\js\release\promise.js:483:18)
at new Promise (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\bluebird\js\release\promise.js:79:10)
at Function.exports.run (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\micro\lib\server.js:24:3)
at Server.server (G:\source\node\微服务\hemera\packages\hemera-web\node_modules\micro\lib\server.js:13:50)
at emitTwo (events.js:106:13)
at Server.emit (events.js:194:7)
at parserOnIncoming (_http_server.js:563:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
but the browser can response ok.
Hi everyone,
I'm trying to choose a microservices framework to use with node
but I really need to be able to integrate it with Eureka since we already have a
microservices infrastructure using Eureka :'(
Does anybody know how to use hemera with Eureka for service register/discovery?
Is there any limitation for running hemera microservices inside Docker? if so, what should be done as workarounds?
when i'm kill the hemera app, but the hemera-web's port still has run.
During installation, this error occurs:
'flow-remove-types' is not recognized as an internal or external command, operable program or batch file.
I'm using:
Based on work of https://github.com/hemerajs/fastify-graceful-shutdown
Is it possible to validate the whole pattern using a custom function like in seneca-joi
?
Example:
seneca.add({
a: 1,
joi$: function (schema) {
return schema.keys({ b: Joi.required() })
}
})
Hii, is there any way to use cache for certains hemera services.
I'm looking for something that I've used in Express, a middleware function that caches end points.
Thanks!
Hi Dustin
Have been following your project, and evaluating all alternatives for a project I am about to rewrite. Have you seen the results posted at https://github.com/icebob/microservices-benchmark?
Do you feel its a fair comparison?
Also I see you have files to do benchmarks, how do I run them?
Hi ! Thanks for Hemera it is a great tool, but some examples do not work.
Provided examples do not work. If you try examples provided with promises here:
https://github.com/hemerajs/hemera#what-hemera-code-looks-like
https://github.com/hemerajs/hemera/blob/master/examples/basic/async-await.js
Every time I obtain these errors:
[2017-07-28T08:44:32.701Z] INFO (hemera-CompanionCube-ab2674533b024d95b6b2bd1f31a473ab/26558 on CompanionCube): Connected!
[2017-07-28T08:44:34.712Z] ERROR (hemera-CompanionCube-ab2674533b024d95b6b2bd1f31a473ab/26558 on CompanionCube): Timeout
TimeoutError
at timeoutHandler (/home/remipassmoilesel/projects/poc-microservice-communications/node_modules/nats-hemera/lib/index.js:1283:21)
at Timeout._onTimeout (/home/remipassmoilesel/projects/poc-microservice-communications/node_modules/nats/lib/nats.js:1242:5)
at ontimeout (timers.js:469:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:264:5)
[2017-07-28T08:44:34.713Z] ERROR (hemera-CompanionCube-ab2674533b024d95b6b2bd1f31a473ab/26558 on CompanionCube): Timeout
TimeoutError
at timeoutHandler (/home/remipassmoilesel/projects/poc-microservice-communications/node_modules/nats-hemera/lib/index.js:1283:21)
at Timeout._onTimeout (/home/remipassmoilesel/projects/poc-microservice-communications/node_modules/nats/lib/nats.js:1242:5)
at ontimeout (timers.js:469:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:264:5)
(node:26558) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TimeoutError: Timeout
(node:26558) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
^C[2017-07-28T08:54:32.016Z] FATAL (hemera-CompanionCube-ab2674533b024d95b6b2bd1f31a473ab/26558 on CompanionCube): process exited
signal: "SIGINT"
[2017-07-28T08:54:32.018Z] INFO (hemera-CompanionCube-ab2674533b024d95b6b2bd1f31a473ab/26558 on CompanionCube): Gracefully shutdown
On api side where is hemera hapi I have basic act request:
createUser(req: HapiRequest, reply: Hapi.ReplyNoContinue) {
let user: UserCreateInterface = req.payload;
return req.hemera.act({ topic: 'user-save', type: 'amerbank', payload: user },
function (err: any, result: any) {
reply(err || result)
})
}
here is add in service:
this.hemera.add({
topic: 'user-save',
type: 'amerbank',
email: Joi.number().required()
}
In logs I get error messaga:
[api - 7554]: 170908/201422.097, [error] message: child "email" fails because ["email" is required], stack: PreValidationError: child "email" fails because ["email" is required]
[api - 7554]: at Joi.validate (/home/master/Documents/trifecta/user-service/node_modules/hemera-joi/index.js:38:18)
But api returns:
Internal server error
why i'm run with:
NODE_ENV=devserver NODE_CONFIG_DIR=./config node /mnt/data/webapps/ra-micro-service/index.js &
and start many node instance like below, and when kill -9 , they are auto restart. why?
root 59761 53.0 0.1 943248 36660 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59767 50.0 0.0 941412 31264 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59772 45.0 0.1 943716 35548 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59795 36.0 0.0 934816 30392 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59801 32.0 0.0 935640 29084 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59807 34.0 0.0 934628 29516 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59814 33.0 0.0 935640 29472 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59825 32.0 0.0 940240 32164 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59832 28.0 0.0 930768 24688 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59842 25.0 0.0 930720 24892 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59852 22.0 0.0 889792 21140 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
root 59858 19.0 0.0 889280 20268 ? Rl 11:14 0:00 node /mnt/data/webapps/ra-micro-service/index.js
couldn't support other languages?
client call code must in hemera.ready() method?
hemera.ready(() => {
hemera.act({
topic: 'math',
cmd: 'add',
a: 1,
b: 2
}, function (err, resp) {
this.log.info(resp, 'Result')
})
})
client call can't as:
hemera.act({
topic: 'math',
cmd: 'add',
a: 1,
b: 2
}, function (err, resp) {
this.log.info(resp, 'Result')
})
directly?
Here is my try:
const hp = require('hemera-plugin');
export class MongoExtend {
public register: any = {
};
constructor() {
this.register.attributes = {
name: 'mongo-store-ext',
description: 'Extend default mongo-store service',
version: '1.0.0'
};
this.register.plugin = hp((options: any, next: any) => {
console.log(this);
next()
});
this.register.options = {}
}
}
const mongoex = new MongoExtend;
hemera.use(mongoex.register);
But it doesn't work
It registers ok, but I don't get hemera instance inside plugin... Anyone know what is a problem?
How could I log additional data like trace$
or request$
?
The context object is not passed to the logger
Using nodejs 7.6.0, I got an NPM error when installing
Being able to install hemera-store
NPM error:
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node',
1 verbose cli '/usr/local/bin/npm',
1 verbose cli 'install',
1 verbose cli 'hemera-store' ]
2 info using [email protected]
3 info using [email protected]
4 verbose stack Error: Cannot find module 'internal/fs'
4 verbose stack at Function.Module._resolveFilename (module.js:470:15)
4 verbose stack at Function.Module._load (module.js:418:25)
4 verbose stack at Module.require (module.js:498:17)
4 verbose stack at require (internal/module.js:20:19)
4 verbose stack at evalmachine.<anonymous>:18:20
4 verbose stack at Object.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/cmd-shim/node_modules/graceful-fs/fs.js:11:1)
4 verbose stack at Module._compile (module.js:571:32)
4 verbose stack at Object.Module._extensions..js (module.js:580:10)
4 verbose stack at Module.load (module.js:488:32)
4 verbose stack at tryModuleLoad (module.js:447:12)
5 verbose cwd /Users/romuald/Documents/devserver/workspace/hemera-playground/microservices-example
6 error Darwin 14.5.0
7 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "hemera-store"
8 error node v7.6.0
9 error npm v4.1.2
10 error code MODULE_NOT_FOUND
11 error Cannot find module 'internal/fs'
12 error If you need help, you may report this error at:
12 error <https://github.com/npm/npm/issues>
13 verbose exit [ 1, true ]
Hi,
I am currently playing around with hemera and was rewriting a small app from seneca. I am using Joi Validation and wanted to test it with the approach that is documented for unit tests.
This is the Plugin I am trying to test:
function EventStorePlugin (options, next) {
this.use(require('hemera-joi'))
this.setOption('payloadValidator', 'hemera-joi')
this.add(
{
topic: 'events',
cmd: 'add',
events: Joi.array().required()
},
(msg, reply) => {
msg.events.forEach(store.add)
reply(null, {success:true})
}
)
next()
}
But it seems that Running unit tests against this, is not checking for Validation:
Test
const Hemera = require('nats-hemera')
const Nats = require('hemera-testsuite/natsStub')
const AddStub = require('hemera-testsuite/addStub')
const nats = new Nats()
const h = new Hemera(nats, { logLevel: 'fatal' })
h.use(require('../handlers'))
test('Requires a valid Event', done => {
expect.assertions(5)
h.ready(() => {
AddStub.run(
h,
{
topic: 'events',
cmd: 'add'
},
{ events: 1 },
(err, res) => {
expect(err).toBeTruthy()
done()
}
)
})
})
Is there a way of getting validation to work with the AddStub?
Problem with PUBSUB:
No handler found for this pattern (PatternNotFound)
server.js
const Hemera = require('nats-hemera');
const nats = require('nats').connect();
const hemera = new Hemera(nats, {logLevel: 'error'});
hemera.ready(() => {
// Add service command
hemera.add({topic: 'service', cmd: 'do'}, (req, cb) => {
cb(null, {result: 'ok! done! - ' + req.data});
// Emit an event (one-to-many)
hemera.act({
pubsub$: true,
topic: 'service',
cmd: 'event',
payload: 'add was executed!'
});
});
// Subscribe to "topic:payment,cmd:event"
hemera.add({pubsub$: true, topic: 'service', cmd: 'event'}, req => {
console.log('event', req);
});
});
subscriber.js
const Hemera = require('nats-hemera');
const nats = require('nats').connect();
const hemera = new Hemera(nats, {logLevel: 'error'});
hemera.ready(() => {
// TODO: Check the problem here
// Subscribe to "topic:payment,cmd:event"
hemera.add({pubsub$: true, topic: 'service', cmd: 'event'}, req => {
console.log('event', req);
});
});
client.js
const Hemera = require('nats-hemera');
const nats = require('nats').connect();
const hemera = new Hemera(nats, {logLevel: 'error'});
hemera.ready(() => {
// Call service command "topic:service,cmd:do"
hemera.act({topic: 'service', cmd: 'do', data: 123}, (err, resp) => {
console.log(err, resp);
});
});
Steps to Reproduce
1. Start server.js (no output)
node server.js
2. Start subscriber.js (no output)
node subscriber.js
3. Start client.js
node client.js
Output (expected output):
null { result: 'ok! done! - 123' }
4. Now check subscriber.js output (PROBLEM)
Expected subscriber.js output:
event { topic: 'service', cmd: 'event', payload: 'add was executed!' }
Actual subscriber.js result (ERROR):
[2017-07-12T11:49:17.033Z] ERROR (hemera-ff254d962b06-fd3d138ee7f34f5181357a5ba2bfc9e1/765 on ff254d962b06): No handler found for this pattern
PatternNotFound
at Hemera._onServerPreRequestHandler (/code/node_modules/nats-hemera/lib/index.js:835:29)
at ctx._extensions.onServerPreRequest.dispatch (/code/node_modules/nats-hemera/lib/index.js:876:74)
at done (/code/node_modules/nats-hemera/lib/util.js:155:15)
at Hemera.onServerPreRequestLoadTest (/code/node_modules/nats-hemera/lib/extensions.js:214:3)
at each (/code/node_modules/nats-hemera/lib/extension.js:65:14)
at iterate (/code/node_modules/nats-hemera/lib/util.js:160:9)
at done (/code/node_modules/nats-hemera/lib/util.js:153:15)
at Hemera.onServerPreRequest (/code/node_modules/nats-hemera/lib/extensions.js:192:3)
at each (/code/node_modules/nats-hemera/lib/extension.js:65:14)
at iterate (/code/node_modules/nats-hemera/lib/util.js:160:9)
[2017-07-12T11:49:17.039Z] ERROR (hemera-ff254d962b06-fd3d138ee7f34f5181357a5ba2bfc9e1/765 on ff254d962b06): No handler found for this pattern
PatternNotFound
at Hemera._onServerPreRequestHandler (/code/node_modules/nats-hemera/lib/index.js:835:29)
at ctx._extensions.onServerPreRequest.dispatch (/code/node_modules/nats-hemera/lib/index.js:876:74)
at done (/code/node_modules/nats-hemera/lib/util.js:155:15)
at Hemera.onServerPreRequestLoadTest (/code/node_modules/nats-hemera/lib/extensions.js:214:3)
at each (/code/node_modules/nats-hemera/lib/extension.js:65:14)
at iterate (/code/node_modules/nats-hemera/lib/util.js:160:9)
at done (/code/node_modules/nats-hemera/lib/util.js:153:15)
at Hemera.onServerPreRequest (/code/node_modules/nats-hemera/lib/extensions.js:192:3)
at each (/code/node_modules/nats-hemera/lib/extension.js:65:14)
at iterate (/code/node_modules/nats-hemera/lib/util.js:160:9)
event { topic: 'service', cmd: 'event', payload: 'add was executed!' }
**Very important: ** Subscriber recevied the event, but with errors.
I'm missing the proper way to test the services (the aither repo doesn't have any besides the load test), and couldn't find a definitive answer. In express, I used superagent, which made the REST testing somewhat easy, and doesn't need to listen on a port
It's should not be possible to register a server method with a topic which is already used by a registered plugin. We have to guarantee that a plugin can be scaled alone.
E.g
use(mongodb)
hemera.Add('topic:mongodb-store,cmd...')
Please answer in this format.
Company | Project size | What would you like to change? | Permission to list your company ? |
---|---|---|---|
name | small, big | everything works like a charm | yes, here is my link to the logo |
I have written some functional tests that are passing (TestSet 1) . I now started to create more tests (in another file) that currently fail (TestSet 2). While having this intermediate situation I observed a rather confusing behaviour:
I run my TestSet 1 which passes fine. Now I run all tests, which fails due to TestSet2. Also Jest does not exit, which usually indicates that there are some connections / processes / async things still happening. I kill jest via sigterm. If I now run TestSet 1 alone again, which previously worked I am getting a PatternNotFound Exception.
Also just restarting the NATS server does not solve the issue.
That TestSet 1 always passes, independent of previously ran TestSet 2.
serverResponseError
only for middleware, extensions or fatal errors not when an error is replied by the user.next
has to be called explicit in the middlewaresend
multiple times shouldn't have side effectsadd
middlewaresexpose
and use prototype based decorations
req.locals
Plugin system is heavily inspired by https://github.com/fastify/fastify
It seems like NATS support message queueing pattern
Unless i missed something, that seems to be missing. Any plan to implement it?
What would be the opinionated way on versioning the microservices? How to have 3-4 versions running side-by-side?
Example code:
hemera.add({ topic : 'test', cmd : 'A' }, function(msg, reply) {
console.log('A');
setTimeout(() => reply(null, { ok : true }), 3000);
});
hemera.add({ topic : 'test', cmd : 'B' }, function(msg, reply) {
console.log('B');
this.act({ topic : 'test', cmd : 'A', timeout$ : 1000 }, function(err, res) {
if ( err ) {
console.log('A err');
reply(err);
} else {
console.log('A res');
reply(null, res);
}
});
});
hemera.act({ topic : 'test', cmd : 'B', timeout$ : 2000 }, (err, res) => {
if ( err ) {
console.log('B err');
} else {
console.log('B res');
}
});
Output:
B
A
A err
B err
A res
B err
After the timeout, when the service replies with a response, the error gets forwarded to the first act call and not the response.
Expected output would be:
B
A
A err
B err
A res
B res
For example, we use winston everywhere, I miss the possibility to link an external logging interface which will be awesome to have. Pino actually breaks our logging stack
I am using mongodb atlas db to store data. When I use find query sometimes it pulls data sometimes it doesn't with the same query...
Here is code snippet:
public showUserByMail(msg: any, done: any): void {
let __this: any = this;
let hemera: T = __this;
hemera.act({
topic: 'mongo-store',
cmd: 'find',
collection: 'users',
query: { email: msg.email }
}, (err: Error, resp: any) => {
if (err) {
done(err);
}
console.log(resp)
if(resp.result.length === 0) {
done(null, false);
} else {
done(null, resp.result[0]);
}
})
}
I have built a simple PubSub example to play around and found the case that some published messages are not received by my receivers.
I was running my subscriber in 2 terminal Windows and my publisher in a third.
Subscriber Code
hemera.ready(function () {
console.log('Ready')
hemera.add({ topic: 'test', pubsub$: true }, function (resp) {
console.log('Subscriber', process.pid, resp.value)
})
})
Publisher Code
hemera.ready(function () {
console.log('Ready')
hemera.act({ topic: 'test', value: 1, pubsub$: true })
hemera.act({ topic: 'test', value: 2, pubsub$: true })
setTimeout(() => {
console.log('After Timeout #1')
hemera.act({ topic: 'test', value: 3, pubsub$: true })
hemera.act({ topic: 'test', value: 4, pubsub$: true })
setTimeout(() => {
console.log('After Timeout #2')
hemera.act({ topic: 'test', value: 5, pubsub$: true })
hemera.act({ topic: 'test', value: 6, pubsub$: true })
console.log('Closing')
hemera.close()
}, 3000)
}, 30)
})
I would expect both subscribers to receive all 6 Messages
It seems that the subscribers only received the first 4 Messages
Although My Publisher seems to send all messages out:
Logs
[2017-07-01T16:59:57.682Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box): Connected!
Ready
[2017-07-01T16:59:57.693Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box):
outbound: {
"id": "757d6b594e194d38a8da9df257edd876",
"pattern": "topic:test,value:1"
}
[2017-07-01T16:59:57.696Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box):
outbound: {
"id": "cbecbb5e42894b579870f34d363470db",
"pattern": "topic:test,value:2"
}
After Timeout #1
[2017-07-01T16:59:57.731Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box):
outbound: {
"id": "c05f8df426494d7396ceb5331207093c",
"pattern": "topic:test,value:3"
}
[2017-07-01T16:59:57.731Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box):
outbound: {
"id": "10d2558844b74025bab7a87f76928722",
"pattern": "topic:test,value:4"
}
After Timeout #2
[2017-07-01T17:00:00.737Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box):
outbound: {
"id": "3735272e43104f67895123e3a0750d63",
"pattern": "topic:test,value:5"
}
[2017-07-01T17:00:00.737Z] INFO (hemera-m0rcs-Macbook.fritz.box-dc94a08f39f54e65b020ed3136591254/57743 on m0rcs-Macbook.fritz.box):
outbound: {
"id": "3b4ad509d8b34237a18a3f5e1d26051d",
"pattern": "topic:test,value:6"
}
Closing
It would be nice if I could switch parambulator for Joi validation for the in/out payload validation.
why i'm use 1.5.6
have some errors
2017-08-25T12:07:06+0800 <debug> app.js:133 (Aedes.self.aedes.authenticate) TypeError: Cannot read property 'request' of undefined
at NatsTransport.sendRequest (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\transport.js:113:19)
at onPreRequestHandler (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\onPreRequest.js:68:31)
at ctx._extensions.onClientPreRequest.dispatch (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\index.js:1019:63)
at done (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\util.js:155:15)
at onClientPreRequestCircuitBreaker (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\extensions.js:116:5)
at each (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\extension.js:28:7)
at iterate (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\util.js:160:9)
at done (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\util.js:153:15)
at onClientPreRequest (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\extensions.js:90:3)
at each (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\extension.js:28:7)
at iterate (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\util.js:160:9)
at Function.serialWithCancellation (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\util.js:163:7)
at Extension.run (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\baseExtension.js:57:10)
at Extension.dispatch (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\extension.js:31:10)
at Hemera.act (G:\repository\ra\ra-broker\node_modules\nats-hemera\lib\index.js:1019:40)
at Aedes.self.aedes.authenticate (G:\repository\ra\ra-broker\app\app.js:110:46)
It would be nice to have the chance to define middleware only for specific add
I prefer a chaining syntax instead parameter overloading.
hemera.add({
topic: 'test',
cmd: 'add'
}).use(function(req, resp, next) {
//process request
})
.end(function(req, cb) {
cb()
})
Approach:
Providing an interface to attach handlers to the actMeta
object. When the add is called we could return an interface.
return new Add(actMeta)
/*
Interface:
use(<function)
end(<function>)
*/
Those handlers can be executed in serial when a message arrived https://github.com/hemerajs/hemera/blob/master/packages/hemera/lib/index.js#L510.
Hi @sberryman I think I found the issue. There is something wrong with the annotations which are send to zipkin. This can take a while but I will fix it. Could you open an issue?
Based on what I saw last night you have an almost identical copy of seneca-zipkin-tracer including the zipkin-simple package.
From zipkin-simple:
Annotation Data contains additional info about the current method:
Does hemera plans to have typescript typings? It's great for new comers to this lib and to ensure proper code structure with self documenting typings
If a timeout error occurs when a service is taking a longer time to respond the act callback is called twice. Once when the timeout error occurs and the second time when the service has finished the request:
Example:
hemera.add({ topic : 'test', cmd : 'timeout' }, (msg, reply) => {
setTimeout(() => { reply(null, { ok : true }) }, 3000);
});
hemera.ready(() => {
hemera.act({ topic : 'test', cmd : 'timeout', timeout$ : 1000 }, (err, res) => {
console.log('done');
console.log(err || res);
});
});
Output:
done
{ TimeoutError
at /home/andrija/Documents/hemera-test/node_modules/nats-hemera/build/index.js:949:21
at Timeout._onTimeout (/home/andrija/Documents/hemera-test/node_modules/nats/lib/nats.js:1165:41)
at ontimeout (timers.js:365:14)
at tryOnTimeout (timers.js:237:5)
at Timer.listOnTimeout (timers.js:207:5)
message: 'Timeout',
pattern: { topic: 'test', cmd: 'timeout', 'timeout$': 1000 } }
done
{ ok: true }
Hii,
Image if you have multiple servers on a NAT, spread by multiple version. What I want to know is, if there's any way to communicate to a specific server version using act command?
The logic behind that is, imagine you have two session servers (0.0.1 and 0.0.9). One specific application requests for something to session server this server depends on 0.0.9, so the request will reach to [email protected]. For some reason that server will crash and the request goes to the other server that is compatible with (ex. 0.0.1).
Thanks!
Before you submit an issue we recommend you drop into the Gitter community and ask any questions you have or mention any problems you've had getting started with hemera.
hemera-web can support custom the route url?
http://localhost:3000/?topic=math&cmd=add&a=10&b=10
like as
http://localhost:3000/math/cmd/?a=10&b=10
Branch | Build failing 🚨 |
---|---|
Dependency | pino |
Current Version | 3.0.1 |
Type | dependency |
This version is covered by your current version range and after updating it in your project the build failed.
As pino is a direct dependency of this project this is very likely breaking your project right now. If other packages depend on you it’s very likely also breaking them.
I recommend you give this issue a very high priority. I’m sure you can resolve this 💪
pino-debug
to readme - #133 - @davidmarkclements
The new version differs by 6 commits .
30a2607
3.0.2
a7b4af1
Merge pull request #133 from pinojs/pino-debug-doc
87d0e70
Merge branches 'pino-debug-doc' and 'pino-debug-doc' of http://github.com/mcollina/pino into pino-debug-doc
ef13b73
fix build
a9d4248
closes #128
0b56336
Do not check for node v0.10 in .travis.yml script.
See the full diff.
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot 🌴
It would be nice if returning a promise from a Hemera.add handler worked the same as using a callback. For example, I would expect both services below to behave identically.
hemera.ready(() => {
let Joi = hemera.joi
const myPromise = (fail) => (
new Promise((resolve, reject) => {
if (fail) {
return reject(new Error('boom'))
}
resolve(42)
})
)
hemera.add({
topic: 'test',
cmd: 'boom',
fail: Joi.boolean().required(),
}, function ({fail}, cb) {
return asCallback(myPromise(fail), cb)
})
hemera.add({
topic: 'test',
cmd: 'boom2',
fail: Joi.boolean().required(),
}, function ({fail}) {
return myPromise(fail)
})
// const cmd = 'boom'
const cmd = 'boom2'
hemera
.act({ topic: 'test', cmd, fail: true })
.then(x => hemera.log.info(x))
.catch(e => console.log(e.stack))
})
cd hemera-add-promise-test
yarn install
npm start
The catch should immediately show a BusinessError
The console shows a deprecation warning for an unhandled promise rejection and the catch shows a Timeout error after the timeout expires.
What's the interest level of adding a Mongodb Database Adapter?
hermera can't support Promise or Async/Await?
I notice that mongo-store
topic is hard coding into the package. How about if I have multiple mongo stores in my services cluster?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.