Further changelogs are tracked in Github releases
- Implement more robust graceful shutdown
- Activate async / await tests in CI
- Remove
exit
event in graceful shutdown routine.
Update bloomrun to 4.0.0
Update tinysonic
to 1.3.0 to fix parsing issues in short json syntax e.g act('a:22de')
, àct('a: null')
The bloomrun
config lookupBeforeAdd
is set to false
by default. This allows to add pattern without to respecting the pattern matching order.
It has no impact on the pattern matching rules.
- Register hemera and plugin errors in errio to use it in
instanceof
comparison. - Any error which is created with
hemera.createError
is registered in errio.
- Throw errors instead emiting
- Remove typings property from package.json
- Remove typescript definition files. Thanks to @vforv we provide official @types/nats-hemera
- update typescript definition files
- Throw error when trying to register plugins with
.use()
inside plugins
- update typescript definition files
- Check for pattern in
act
andadd
and throw error when pattern is undefined
- Check if pattern is not undefined in
act
- dump version
- Check if pattern is not undefined in
act
Functional style in extensions and life-cycle-events. In future we can provide a more consistent and encapsulated interface.
- hemera-joi
- hemera-avro
- hemera-redis-cache
- hemera-jwt-auth
- hemera-mongo-store
- hemera-rethinkdb-store
- hemera-parambulator
- hemera-slackbot
- hemera-web
- hemera-zipkin
- hemera-nats-streaming
- Extension and Life-cycle hooks are no longer scoped with the current hemera instance we pass the instance as the first argument
- Extensions
Old:
hemera.ext('onServerPreRequest', function (req, res, next) {
const ctx = this
next()
})
hemera.ext('onClose', (done) => {
const ctx = this
done()
})
New:
hemera.ext('onServerPreRequest', function (ctx, req, res, next) {
next()
})
hemera.ext('onClose', (ctx, done) => {
done()
})
- Life-cycle events
Old:
hemera.ext('clientPostRequest', function () {
const ctx = this
})
New:
hemera.ext('onServerPreRequest', function (ctx) {
next()
})
Lerna issues
Much better Typescript support
Implement a new interface to create a pipeline for encoding and decoding the messages. hemera-msgpack
, hemera-snappy
and hemera-avro
was updated.
New:
// Replace the default decoder/encoder
hemera.decoder.reset(decode)
hemera.encoder.reset(decode)
// Remove all steps
hemera.decoder.reset()
// Move the pipeline at the first place e.g for compressing algorithms
hemera.decoder.first(uncompress)
// Add a new pipeline step
hemera.decoder.add(function() {
return { value: <payload>, error: <error> }
})
The close
method is async and accept a callback. Before the close callback is called all registered subscriptions are unsubscribed from NATS as well as all registered pattern. Plugins which have been registered an onClose
extension can clean up. Every IO will be flushed to NATS before the close callback is called.
- Upgrade time: low - none to a couple of hours for most users
- Complexity: low - requires following the list of changes to verifying their impact
- Risk: none
- Dependencies: low - existing plugins will work as-is
- The
close
method is async and accept a callback
- If you want to check the error from the
onClose
extension you can do: Old:
hemera.close()
New:
hemera.close((err) => ...)
- The callback of your tests should be called in the
onClose
handler otherwise the server won't gracefully shutdown before the next test can start.
Old:
hemera.close()
New:
hemera.close(done)
- When removing a topic with
remove(<topic>)
all pattern which belongs to it will be deleted.
- Fixed some config default values and document options.
- Validate config with Joi
- Fixed request duration calculation
- Remove redundant data from protocol (
request.timstamp
andrequest.duration
already present intrace
) - Make Pino PrettyLogger optional so we can consume the JSON output stream.
- Humanize duration property in request logging
- Log out- and inbound requests in log level
debug
- Cover NATS permission error, gracefully shutdown of hemera on irrevocable connection issues
- Create plugin class
- Emit error when plugin was not initialized within the allowed timeout
- Add pattern to
PATTERN_ALREADY_IN_USE
Error
- Gracefully shutdown also when hemera is exited by
hemera.fatal
- Remove
signal-exit
package and implement a much simpler signal handler to gracefully exit hemera. - Gracefully shutdown: We will unsubscribe all active subscriptions.
- Gracefully shutdown: We will wait until the client has flush all messages to nats.
- Attach
trace$.method
to errorDetails.
- Clean code
- Allow using custom queue group names via
queue$
property inadd
pattern.
- We support Async/Await (Node 7.6+), Generators and error-first-callback by default. You don't have to set any options. The
generators
options was removed.
- Critical - Fixed finite loop when we have nested call chain of
act
and the last one does not provide a callback.
- Add
tag
property to tagging hemera instances. Used inhemera-zipkin
to indicate the server instance.
- Remove passing index and previous value as parameter
hemera.ext(req, resp, next, prevValue, index)
- Move reply logic from server response to reply.js class
- Update tests
- Add new
onClose
extension point to gracefully shutdown services like hemera-mongo-store and hemera-web - Declare minimum hemera version in hemera-mongo-store and hemera-web
- Remove .eslintrc, eslint dependencies from nats-hemera package
- Use hemera-plugin in all hemera plugins
- Remove check for dependencies, the developer is responsible for that
- Remove check for duplicate dependencies, the developer is responsible for that
- Remove eslint packages from plugins. We use the root package as linter
- Use
standard
package to lint. - Create new hemera-plugin which checks that the bare-minimum version of Hemera is installed and provide a consistent interface to create plugins.
- Add tests for
hemera-plugin
- Update docs and examples
- Remove
dependencies
property from all hemera packages - Remove eslint, editorconfig from all hemera packages
- Use
safe-buffer
in hemera-avro package
Hemera is no longer responsible to handle plugin dependencies.
- Simplifiy dependency management. Dependencies are installed from the plugin it needs. Since NPM 3 a clean dependency graph is guaranteed.
- Plugin helper hemera-plugin
- Always use hemera-plugin if you want to create a plugin. Example
- Check if any plugins has installed the correct dependencies.
- Generate unique node id
- Unsubscribe subscription by id
- Update streaming example
- Emit errors instead throw them because they will be thrown by convention when no error handler exist. This improves async error handling.
- Don't manipulate original plugin options
- Introduce blacklist for error propertys
- Add tests
- Introduce
childLogger
for plugins: It uses internally the child bindings of Pino therefore only possible with default logger Pino. - Add tests
Example:
[2017-05-21T12:11:05.818Z] INFO (hemera-starptech/17328 on starptech):
plugin: "hemera-web"
inbound: {
"id": "33badc7834f541faaf3f4d79a8958715",
"duration": 0.005121,
"pattern": "a:1,b:2,cmd:add,topic:math"
}
- Add
close
event: Is fired before the transport connection is closed.
- Fire next when server is listening
- Add tests
- Fixed content type parsing
- Configuration: When load policy has been breached we can gracefully exit the process
load: {
shouldCrash: true, // Should gracefully exit the process to recover from memory leaks or load, crashOnFatal must be enabled
}
- Improve NATS subject to RegexExp conversion. Support all subject levels
a.*.b
,a.>
.
- Add support for full / token wildcards in topic name details
- Add wildcard example
- Add tests for wildcards
- Convert server / client handler to instance members (performance)
- Move circuit breaker middleware only on client side circuit breaker
- Add tests for callback and promise error handling
- Add test for timeouts
- Circuit breaker is disabled by default and is configurable
- Implement circuit breaker
- Add tests for callback and promise error handling
- Fixed util.pattern, don't concatenate objects to
[object Object]
- Add tests
- Rename some files to *.spec.js
- Remove referrers meta$ property after recursion error to reduce payload size
Manage plugin dependencies. The dependencies
attribute is used to identify the dependencies of a plugin. When the plugin could not be resolved a warning appears and an error is thrown. Does not provide version dependency which should be implemented using npm peer dependencies.
exports.plugin = function myPlugin (options) {
var hemera = this
hemera.add({
topic: 'math',
cmd: 'add'
}, (req, cb) => {
cb(null, req.a + req.b)
})
}
exports.options = {}
exports.attributes = {
dependencies: ['hemera-joi'],
pkg: require('./package.json')
}
Error Message
Plugin `myPlugin` requires `hemera-foo` as dependency. Please install with 'npm install --save hemera-foo'
Throw only on NATS connection issues. Complete NATS connection error codes. Ensure that we cover all possible cases.
Throw only on NATS connection issues. Authorization and Protocol issues are logged but don't lead to a process termination.
hemera 1.2.0 is focused on error handling, plugin dependencies
- Upgrade time: low - none to a couple of hours for most users
- Complexity: low - requires following the list of changes to verifying their impact
- Risk: medium - type checks on error will fail because the hemera error was stripped
- Dependencies: low - existing plugins will work as-is
You get the exact error you have sent. Errors are wrapped only for framework errors (Parsing errors, Plugin registration errors, Timeout errors) or logging.
- Enable Server policy to abort requests when the server is not able to respond cause (max memory, busy event-loop). Example Configurable
- Long stack traces by default. Configurable
- Detect message loops (abort the request and return an error). Example Configurable
- Enrich errors logs with details (pattern, app-name, timestamp).
- Track network hops in error to identify which clients was involved. Example
- Pull the wrapped error one level up. For any case except for: HemeraParseError, HemeraError "Error during plugin registration, TimeoutError"
Old:
hemera.add({
topic: 'email',
cmd: 'send'
}, (resp, cb) => {
cb(new Error('Uups'))
})
hemera.act({
topic: 'email',
cmd: 'send',
email: '[email protected]',
msg: 'Hi!'
}, (err, resp) => {
expect(err).to.be.exists()
expect(err.name).to.be.equals('BusinessError')
expect(err.message).to.be.equals('Business Error')
expect(err.cause.name).to.be.equals('Error')
expect(err.cause.message).to.be.equals('Uups')
hemera.close()
done()
})
New:
hemera.add({
topic: 'email',
cmd: 'send'
}, (resp, cb) => {
cb(new Error('Uups'))
})
hemera.act({
topic: 'email',
cmd: 'send',
email: '[email protected]',
msg: 'Hi!'
}, (err, resp) => {
expect(err).to.be.exists()
expect(err.name).to.be.equals('Error')
expect(err.message).to.be.equals('Uups')
hemera.close()
done()
})
-
All logs are wrapped with the correct Hemera error subclass BusinessError, FatalError ...
-
Plugin dependencies are declared with peerDependencies instead with
dependencies
property in the plugin.
Old:
exports.attributes = {
dependencies: ['hemera-joi']
pkg: require('./package.json')
}
New:
"peerDependencies": {
"hemera-joi": "^1.0.4",
"nats-hemera": "1.x || 2.x"
}