Skip to content

Commit

Permalink
[api] [refactor] Assume no chain by default #39
Browse files Browse the repository at this point in the history
  * Switches default back to end response on exit
    * Least surprising behavior for users 
    * Is more frequent use-case
  * Adds configuration options for chaining
  * Updates examples and tests to new API
  • Loading branch information
Marak committed Dec 1, 2017
1 parent dd36244 commit 68ebdf8
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 16 deletions.
2 changes: 2 additions & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ Since `v5.1.0` and above, `microcule` is able to compose multiple functions toge

In order to chain multiple services, simply call them as standard Node.js middlewares in the order you want them to execute.

Note: You must specify the `chain` parameter of `spawn()` as `true`, or else microcule will automatically end the response after the first middleware executes.

```js
app.use([logger(), basicAuthHandler, bashServiceHandler, nodeServiceHandlerA, nodeServiceHandlerB], function (req, res) {
console.log("No services ended response, made it to end");
Expand Down
11 changes: 2 additions & 9 deletions examples/express-any-binary.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,10 @@ var handler = microcule.plugins.spawn({
argv: ['hello', 'world']
});

// tail the ReadMe.md file
// any changes to ReadMe.md in root of project will stream to client
/*
var handler = microcule.plugins.spawn({
bin: 'tail',
argv: ['-f', 'ReadMe.md'],
config: {
SERVICE_MAX_TIMEOUT: 60000
}
bin: 'sh',
argv: ['-c', 'echo "foo" | cat']
});
*/

// spawn simple ls command to show current directories
/*
Expand Down
9 changes: 6 additions & 3 deletions examples/express-chain-services.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ var bashService = 'echo "hello bash"'

var handlerA = microcule.plugins.spawn({
code: nodeService,
language: "javascript"
language: "javascript",
chain: true
});

var handlerB = microcule.plugins.spawn({
code: nodeServiceB,
language: "javascript"
language: "javascript",
chain: true
});

var bashHandler = microcule.plugins.spawn({
code: bashService,
language: "bash"
language: "bash",
chain: true
});


Expand Down
18 changes: 16 additions & 2 deletions lib/plugins/spawn/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,23 @@ module['exports'] = function spawnService (service) {
}
*/

// If source code passed in is a JavaScript function in memory, create a small module shim to export the function
if (typeof _service.code === "function") {
_service.code = "module.exports = " + _service.code.toString();
}

// the default behavior with no additional options is to close the request after first process exits
if (typeof service.endResponseOnExit === 'undefined') {
service.endResponseOnExit = true;
}

// if the chain option has been set to true, do not endResponseOnExit
// this allows for the processing of several spawned services in sequence without closing the response to the client
// note: "chain" option acts as an alias for endResponseOnExit
if (service.chain === true) {
service.endResponseOnExit = false;
}

// only configure compiled middleware plugin *once* ( same as how all other plugins are configured )
// probably not a good idea to attempt to confifigure compile plugin inside of spawnServiceMiddleware() handler
var _compile;
Expand Down Expand Up @@ -521,7 +534,7 @@ module['exports'] = function spawnService (service) {
serviceCompletedTimer = clearTimeout(serviceCompletedTimer);
serviceCompleted = true;
// dump stderr and perform logging events
status.stderrOutput.forEach(function(e){
status.stderrOutput.forEach(function (e) {
// if the response is erroring, then send errors to stdout ( should still be open )
if (status.erroring === true && service.redirectStderrToStdout) {
// send the stderr data to the fd3 handler as an error
Expand All @@ -536,7 +549,8 @@ module['exports'] = function spawnService (service) {
// Note: Only certain languages are currently capable of acting as middlewares
// For additional language support, we need an explcit event / API in each language for closing event over pipe3 ( similiar to how javascript services work )
var middlewareEnabledLanguages = ['javascript', 'babel', 'coffee-script'];
if (status.serviceEnded) {

if ((status.serviceEnded || service.endResponseOnExit === true)) {
// If the service has ended ( meaning res.end() was called, or sent via pipe3 message ),
// then we will end the response now ( no more middlewares will process)
output.end();
Expand Down
8 changes: 6 additions & 2 deletions test/service-as-middleware-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test('attempt to create a few chainable microservice spawn handlers', function (

handlers['basicAuth'] = microcule.plugins.spawn({
language: "javascript",
chain: true,
code: function (req, res, next) {
var auth = require('basic-auth')
var credentials = auth(req)
Expand All @@ -31,18 +32,21 @@ test('attempt to create a few chainable microservice spawn handlers', function (

handlers['write-a'] = microcule.plugins.spawn({
language: "bash",
code: 'echo "a"'
code: 'echo "a"',
chain: true
});
handlers['write-b'] = microcule.plugins.spawn({
language: "javascript",
chain: true,
code: function (req, res, next) {
res.write('b\n');
next(); // call next() to indicate this services is not going to explictly end the response
}
});
handlers['write-c'] = microcule.plugins.spawn({
language: "bash",
code: 'echo "c"'
code: 'echo "c"',
chain: true
});
t.end();
});
Expand Down

0 comments on commit 68ebdf8

Please sign in to comment.