Progressive microservices framework for Node.js
MIT License
Published by icebob over 7 years ago
Implemented pluggable serializers.
Built-in serializers:
Usage
let JSONSerializer = require("moleculer").Serializers.JSON;
let broker = new ServiceBroker({
serializer: new JSONSerializer(),
transporter: new Transporter(),
nodeID: "node-1"
});
Created an index.d.ts file. I'm not familiar in Typescript, so if you found error please help me and open a PR with fix. Thank you!
Added metricsRate
options to broker. This property sets the rate of sampled calls.
1
means to metric all calls0.5
means to metric 50% of calls0.1
means to metric 10% of callsUsage
let broker = new ServiceBroker({
metrics: true,
metricsRate: 0.1
});
Added meta
prop to Context
. The meta
will be merged if has parent context.
In case of remote calls the metadata will be transfered to the target service.
Usage
Set meta in broker.call
:
// Broker call with meta data
broker.call("user.create", { name: "Adam", status: true}, {
timeout: 1000,
meta: {
// Send logged in user data with request to the service
loggedInUser: {
userID: 45,
roles: [ "admin" ]
}
}
})
Access meta in action:
broker.createService({
name: "user",
actions: {
create(ctx) {
const meta = ctx.meta;
if (meta.loggedInUser && meta.loggedInUser.roles.indexOf("admin") !== -1)
return Promise.resolve(...);
else
throw new CustomError("Access denied!");
}
}
});
Benchmarkify updated & created continuous benchmarking with bench-bot.
Bench-bot is a benchmark runner. If a new Pull Request opened, bench-bot will run benchmarks against the master
branch and it will post the results to the PR conversation.
Transit
to ServiceBroker
wrapContentAction
500
createSubContext
ctx.parent
and added ctx.parentID
let ctx = new Context(broker, action);
ctx.setParams({ a: 5 });
ctx.generateID(); // for metrics
ctx.requestID = requestID;
const p = broker.call("user.create");
console.log("Context:", p.ctx);
If an event triggered remotely on an other node, broker passes the nodeID of sender to the event handler as 2nd parameter.
// Usage in subscription
broker.on("**", (payload, sender) => console.log(`Event from ${sender || "local"}:`, payload));
// Usage in Service schema
broker.createService({
...
events: {
something(payload, sender) {
console.log(`Something happened on '${sender}':`, payload);
}
}
});
Moleculer uses distributed timeouts.In the chained calls the ctx.call
decrement the original timeout value with the elapsed time. If the new calculated timeout is less or equal than 0, it'll skip the next calls because the first call is rejected with RequestTimeoutError
error.
Published by icebob over 7 years ago
The previous validatorjs
validator removed and added own very fast fastest-validator library. It can 3M validations/sec. Hereafter validation is not the bottle-neck. Only -7% slower with validation.
Here is the new benchmark result:
Suite: Call with param validator
√ No validator x 588,463 ops/sec ±1.11% (84 runs sampled)
√ With validator passes x 541,903 ops/sec ±1.41% (84 runs sampled)
√ With validator fail x 25,648 ops/sec ±1.62% (85 runs sampled)
No validator 0.00% (588,463 ops/sec)
With validator passes -7.91% (541,903 ops/sec)
With validator fail -95.64% (25,648 ops/sec)
Example params definition:
mult: {
params: {
a: { type: "number" },
b: { type: "number" }
},
handler(ctx) {
return Number(ctx.params.a) * Number(ctx.params.b);
}
}
Validation error object:
[ {
type: 'number',
field: 'b',
message: 'The \'b\' field must be a number!'
} ]
fatal
and trace
);log
level. Use info
level instead.Available levels:
logger.trace("trace level");
logger.debug("debug level");
logger.info("info level");
logger.warn("warn level");
logger.error("error level");
logger.fatal("fatal level");
Logger fallback levels:
trace
-> debug
-> info
debug
-> info
info
: main level, no fallbackwarn
-> error
-> info
error
-> info
fatal
-> error
-> info