Conversation
packages/mu-http/driver.js
Outdated
| sendTo.response.write(stringify(message)) | ||
| sendTo.response.end() | ||
| } else { | ||
| cb && cb(mue.transport('connection has alredy recieved response!')) |
There was a problem hiding this comment.
what if there is no callback?
There was a problem hiding this comment.
Then it fails silently of course... :) actually that check was put in place whilst I was working on the last merge - will remove it and assume that the callback is always there this is a safe assumption as driver is an internal thing. Without the check it will blow up with no callback which is the correct behaviour
packages/mu-http/driver.js
Outdated
| port: options.target.port, | ||
| method: 'POST', | ||
| path: '/', | ||
| headers: {'Content-Type': 'application/json'}}) |
There was a problem hiding this comment.
You should use an Agent here to speed things up. creating a new TCP connection for each things.
There was a problem hiding this comment.
agreed - will update
packages/mu-http/driver.js
Outdated
| var req = http.request({host: options.target.host, | ||
| port: options.target.port, | ||
| method: 'POST', | ||
| path: '/', |
There was a problem hiding this comment.
probably a good idea to use a mu-specific path.
There was a problem hiding this comment.
fair enough - /mu/ ?
|
|
||
| req.on('error', function (err) { | ||
| cb(mue.transport(err)) | ||
| }) |
There was a problem hiding this comment.
we should try to avoid some of those closures for speed reasons.
There was a problem hiding this comment.
yep - I'll leave one for later - premature optimization and all that...
| if (cb) { | ||
| setImmediate(function () { | ||
| server.close(cb) | ||
| }) |
There was a problem hiding this comment.
why the setImmediate wrap?
There was a problem hiding this comment.
Again one for @davidmarkclements - I assume the intent is to allow existing I/O to drain - but probably not needed...
There was a problem hiding this comment.
I can't remember why - but this is definitely needed - at least in the tcp transport.
after destroying the connections, and immediately closing I think it goes into a zombie state and keeps the port open - the setImmediate solved this
the problem was hard to reproduce, it was intermittent, but the tests would sometimes fail because of it
There was a problem hiding this comment.
Stick a comment in there. Plus, it's a code smell that something is very wrong in the tear down sequence. It should not be needed.
There was a problem hiding this comment.
good point - also worth digging into this to understand fully - most likely we could expose this condition with some load testing
| connectionsByIp[request.socket.remoteAddress + '_' + request.socket.remotePort] = [] | ||
| } | ||
| connections[inbound.value.protocol.src].push({request: request, response: response}) | ||
| connectionsByIp[request.socket.remoteAddress + '_' + request.socket.remotePort] = inbound.value.protocol.src |
There was a problem hiding this comment.
why are we doing this? an http request is not a socket, and it can't be reuse.
also, we should probably use http://npm.im/end-of-stream to handle all possible cases (including errors)
There was a problem hiding this comment.
Because that connection is written to later in the pattern handling sequence and then removed. https://github.com/apparatus/mu/blob/http_transport/packages/mu-http/driver.js#L41-L45
There was a problem hiding this comment.
oooh, now I understand. perfect.
packages/mu-http/driver.js
Outdated
| server = options.source && listen(options.source.port, options.source.host, options.ready) | ||
|
|
||
| if (!server && options.ready instanceof Function) { | ||
| options.ready() |
There was a problem hiding this comment.
why we ended up having ready()? I thought we had no callbacks at all for transports, services, etc.
There was a problem hiding this comment.
Memory is hazy on this, but there was definitely a good reason, I think it was needed for tests (or rather to avoid using setTimeouts in tests) - and may also be needed internally
There was a problem hiding this comment.
If we need to have a ready() thing, we can just have a full-blown plugin system like boot-in-the-arse and be done with it. Ready callbacks are tricky when there are multiple ones to be started.
There was a problem hiding this comment.
nooooo plugins!!!!! let me review the whole ready thing
There was a problem hiding this comment.
So whilst this is not generally needed, there may be edge cases when a signal back from the underlying driver to indicate that it is ready may be useful. I suggest that we keep this in for now and review after some more field testing if unused.
There was a problem hiding this comment.
@pelger I think it is needed. And if it is needed, you are off with something like https://github.com/mcollina/boot-in-the-arse rather than cooking up something internal.
If it is not needed, we are better off without! :)
davidmarkclements
left a comment
There was a problem hiding this comment.
overall awesomeness - just a couple of requests
|
|
||
| inbound = parse(Buffer.concat(body)) | ||
| receive(inbound.err, inbound.value) | ||
| }) |
There was a problem hiding this comment.
what if the response stream emits an error or closes unexpectedly - maybe end-of-stream needed here
There was a problem hiding this comment.
parse will fail and inbound.err will be set.
| headers: {'Content-Type': 'application/json'}}) | ||
|
|
||
| req.on('response', function (response) { | ||
| response.on('data', function (chunk) { |
There was a problem hiding this comment.
on a general note, I'm concerned we're missing the ability to stream from transport to user land (c.f. #46)
yes there has to of course be a buffering mode (which is our only option), but for large data blobs being able to pattern match against a stream and/or associate a pattern to a stream across every transport would remove all limitations
There was a problem hiding this comment.
This would be good - suggest that we merge this in and then add this capability to the roadmap - would like to think this through a little!
packages/mu-http/driver.js
Outdated
| }) | ||
|
|
||
| req.write(stringify(message)) | ||
| req.end() |
There was a problem hiding this comment.
you can just do req.end(stringify(message))
packages/mu-http/driver.js
Outdated
|
|
||
|
|
||
| function listen (port, host, ready) { | ||
| server = http.createServer() |
There was a problem hiding this comment.
principle of least surprise would encourage assignment to variables as early as possible,
in the tcp transport listen returns the server object, and at the top, server is assigned to the result of listen - could we follow the same approach here (and all transports) ?
There was a problem hiding this comment.
realise listen returns server - no need to assign to server var here
packages/mu-http/driver.js
Outdated
| * HTTP transport | ||
| * Figure out path mapping - perhaps this may need to be part of the config for now just / | ||
| */ | ||
| module.exports = function createTcpDriver (options) { |
There was a problem hiding this comment.
function should be named createHttpDriver
| function send (message, cb) { | ||
| var sendTo | ||
|
|
||
| if (connections[message.protocol.dst]) { |
There was a problem hiding this comment.
suggest breaking the two main cases into two functions - primarily for readability - but also makes inlining more likely
packages/mu-http/driver.js
Outdated
|
|
||
|
|
||
|
|
||
| server = options.source && listen(options.source.port, options.source.host, options.ready) |
There was a problem hiding this comment.
this should be at the top - see previous comments
| return | ||
| if (!msg || !msg.protocol) { | ||
| return | ||
| } else { |
There was a problem hiding this comment.
no need for else after early return
There was a problem hiding this comment.
Ermmm... you want to just re-read that code Dave :)
There was a problem hiding this comment.
I re-read... I'm seeing a return and then an else - the else is redundant - what am I missing?
packages/mu-transport/index.js
Outdated
| protocol: {}} | ||
| var elt = muid | ||
|
|
||
| /* istanbul ignore else */ |
There was a problem hiding this comment.
not keen on artificially maintaining coverage
question is, if we have to do this, maybe the checks aren't necessary
if they are, then we should test (and handle) the alternatives
There was a problem hiding this comment.
Agreed - but IMO the occasional pragma to maintain 100% is worth it - branch coverage is sometimes too fiddly :)
There was a problem hiding this comment.
I submit that its worth the investment for core - the fiddling can reveal things not thought of, or if not it gives confidence that the logic is sound and cases well covered
There was a problem hiding this comment.
Fair comment - however this is 1/2 a days worth so I'll put it on the backlog for now!
There was a problem hiding this comment.
Please remove that sentence, so we do not forget about it. It's ok if coverages drops consequently.
| if (!msg || !msg.protocol) { | ||
| return | ||
| } else { | ||
| msg = constructFailResponse(err, msg) |
There was a problem hiding this comment.
this is much better than before
mcollina
left a comment
There was a problem hiding this comment.
Some nits should be fixed.
packages/mu-http/driver.js
Outdated
| server = options.source && listen(options.source.port, options.source.host, options.ready) | ||
|
|
||
| if (!server && options.ready instanceof Function) { | ||
| options.ready() |
There was a problem hiding this comment.
@pelger I think it is needed. And if it is needed, you are off with something like https://github.com/mcollina/boot-in-the-arse rather than cooking up something internal.
If it is not needed, we are better off without! :)
| function send (message, cb) { | ||
| var sendTo | ||
|
|
||
| if (connections[message.protocol.dst]) { |
| }) | ||
|
|
||
| request.on('end', function () { | ||
| inbound = parse(Buffer.concat(body)) |
There was a problem hiding this comment.
It is way better to use strings here, e.g.:
var body = ''
request.setEncoding('utf8')
request.on('data', (chunk) => body += chunk)There was a problem hiding this comment.
Is it better to use strings or to concat actual buffers? (instead of using array)
| request.on('end', function () { | ||
| inbound = parse(Buffer.concat(body)) | ||
|
|
||
| if (!connections[inbound.value.protocol.src]) { |
There was a problem hiding this comment.
you should protect for inbound.value.protocol.src to exist before proceeding.
packages/mu-transport/index.js
Outdated
| protocol: {}} | ||
| var elt = muid | ||
|
|
||
| /* istanbul ignore else */ |
There was a problem hiding this comment.
Please remove that sentence, so we do not forget about it. It's ok if coverages drops consequently.
|
|
||
| request.on('data', function (chunk) { | ||
| body.push(chunk) | ||
| }) |
There was a problem hiding this comment.
are you doing anything with body here?
No description provided.