Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: emit events about connection messages #252

Closed
wants to merge 5 commits into from
Closed

Conversation

lundibundi
Copy link
Member

As discussed I add events to the connection, also events about connection establishment and destruction already exist on server ('connect', 'disconnect').
Also I did not forward connection events through a server as this will most likely have a significant performance cost, especially during highload. And it's easy to implement if user ever needs it:

server.on('connect', (connection) => {
  common.forwardMultipleEvents(connection, server,
    ['handshakeRequest', 'call', 'event', 'inspect']);
});

Fixes: #250

@@ -384,6 +384,8 @@ class Connection extends EventEmitter {

this.server.startSession(this, application, authStrategy, credentials,
this._onSessionCreated.bind(this));

this.emit('handshakeRequest', applicationName, authStrategy, credentials);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should emit credentials here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@belochub also not sure about that, but I thought that users may decide for themselves whether they need to log them or just ignore this parameter. @metarhia/jstp-core?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi, it won't be secure that way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@belochub It won't be secure it user decides to log them, but they may have different trade-offs there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi, I meant providing the user an ability to log them isn't secure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi, ping. You haven't changed it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes because I see no need to, we are not responsible for users breaking their security by themselves.

@belochub
Copy link
Member

@lundibundi, we also discussed the possibility to log all of the incoming/outgoing messages in debug mode, and I haven't found the implementation of corresponding events here. Will you add it later?

@lundibundi
Copy link
Member Author

@belochub yeah, but should we just emit them as well when node is in debug mode?

Copy link
Member

@nechaido nechaido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality is ok, but i don't like the tests. If you add new functionality, you should provide new tests, that will pass with suggested changes but won't pass without them. Existing tests must be changed only after breaking API change.

@@ -13,6 +13,17 @@ const serverConfig =
let server;
let connection;

function addCallEventCheck(test, connection, iface, calledName, providedArgs) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to add one test that will check that event is emited with the right payload, there is no need to test this every time. If you insist on doing so, I'd prefer the function to be at the end of file.

@belochub
Copy link
Member

@lundibundi, we discussed that there will be different modes and in "debug" or "verbose" mode all of the messages will be emitted.


const application = new jstp.Application(app.name, app.interfaces);
const serverConfig =
{ applications: [application], authPolicy: app.authCallback };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: maybe split this object over several lines? It's a bit long.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Btw we've got the same code in connection-call.js, We should probably also change it there.

const port = server.address().port;
const socket = net.connect(port);
socket.on('error',
() => test.fail('must create socket and connect to server'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can you please use braces here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

() => test.fail('must create socket and connect to server'));
socket.on('connect', () => {
serverConnection.on('handshakeRequest',
(applicationName, authStrategy, credentials) => {
Copy link
Member

@aqrln aqrln Jul 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a missing indentation level. It's strange that ESLint does not complain, it's exactly the bug that was fixed in the indent rule in eslint@4, AFAIU. UPD: nope, it does. The CI has failed because of it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I forgot to update local eslint.

const port = server.address().port;
const socket = net.connect(port);
socket.on('error',
() => test.fail('must create socket and connect to server'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add braces here too?

() => test.fail('must create socket and connect to server'));
socket.on('connect', () => {
serverConnection.on('handshakeRequest',
(applicationName, authStrategy, credentials) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing indentation.

Copy link
Member

@aqrln aqrln left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with style nits.

Copy link
Member

@nechaido nechaido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

test.equal(connection.sessionId, app.sessionId,
'session id must be equal to the one provided by authCallback');
connection.close();
test.end();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed this bit, is it absolute that this callback will be called after both handshake event handlers? If not - test will fail because of assertions after end, in that case the right way to do it is using test.plan(). Same applies to every test here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why I made them like this. Though that's implementation specific to be precise, so maybe it'll be better to use plan? @metarhia/jstp-core should we switch to plan here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, if we multiple callbacks\handlers must be called, it is better to use test.plan().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh well, nobody seems to bother, but I guess the less implementation specific test are the better so I'll change it.

Copy link
Member

@nechaido nechaido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed approve until #252 (review).

@lundibundi
Copy link
Member Author

@metarhia/jstp-core ping.

Copy link
Member

@nechaido nechaido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -377,6 +397,8 @@ class Connection extends EventEmitter {
this, application, authStrategy, credentials,
this._onSessionCreated.bind(this)
);

this.emit('handshakeRequest', applicationName, authStrategy, credentials);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi, I am still against emitting credentials here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@belochub And I still see no harm in doing that. Let's wait what others have to say on this matter.

Copy link
Member

@nechaido nechaido Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@belochub @lundibundi what if we emit them only in debug mode, but in release mode we omit them?

Copy link
Member Author

@lundibundi lundibundi Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes no difference, in debug mode you have whole packets emitted, so there is no reason to make such a switch. Either we emit them or we don't, as I see it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi if you put it this way, I agree with @belochub because I see no use in emiting credential in release mode.

Copy link
Member

@belochub belochub Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi, that's why I'm opting for not emitting them here: if a user will need to debug application including authentication he/she can easily do that by getting complete messages.
And outside of the debug mode emitting credentials makes no sense, no one should use them in that case, because logging them will lead to security problems (and you agree on this).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@belochub Okay, I'll remove it soon.

@nechaido nechaido added this to the 1.0.0 milestone Jul 21, 2017
@nechaido
Copy link
Member

@tshemsedinov ping.

addCallEventCheck(test, server.getClients()[0], iface, methodName, args);
connection.on('callback', (error, ok) => {
test.assertNot(error, 'callMethod must not return an error');
test.strictSame(ok, [42], 'Ok contents must match');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

}
);

test.test('must emit event on call with no arguments and return value',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"with no arguments and return value" is a bit misleading: it is not clear if "no" does also relate to "return value".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we should change this in the connection tests, as it's the same there.

});
});

test.test('must emit packets in not "production" mode', (test) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's either "development" or "production" mode, you can replace "not production" with "development".

test.fail('must create socket and connect to server');
});
socket.on('connect', () => {
serverConnection.on('handshakeRequest',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason of adding listeners here but not on line 53?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wanted to put them in one place, also this callback should always be called after the one above, but it's okay to put them there too.

test.fail('must create socket and connect to server');
});
socket.on('connect', () => {
serverConnection.on('handshakeRequest',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Member

@nechaido nechaido Jul 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO this test is also redundant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd test both as I see no harm in doing so.

}
);

test.test('must emit event on call with no arguments and return value',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests is redundant. Bacause of this addCallEventCheck() should be inlined in a previous test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay

// 4 packets from call below and 4 from 1 heartbeat
test.plan(8);

const clientSentPackets = [{}, { call: [1, 'calculator'], answer: [] }];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer this test not to start handshake. this way there will be no need for tap-oneOf.

Copy link
Member Author

@lundibundi lundibundi Jul 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nechaido You meant heartbeat? I don't really care, I thought that we should test that it emits heartbeat packets as it's easy to miss them especially with our current implementation that writes them directly to transport.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lundibundi I mean that we should test them separately.

@@ -193,6 +197,10 @@ class Connection extends EventEmitter {
_heartbeatCallback(interval) {
this.transport.send('{}');
this.setTimeout(interval, this._heartbeatCallbackInstance);

if (process.env.NODE_ENV !== 'production') {
this.emit('sentPacket', this._heartbeatMessage);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heartbeat should have it's own heartbeat event.

@coveralls
Copy link

coveralls commented Jul 26, 2017

Coverage Status

Coverage increased (+1.2%) to 82.192% when pulling 900917b on add-conn-events into 4d76172 on master.

@metarhia metarhia deleted a comment from coveralls Jul 27, 2017
@metarhia metarhia deleted a comment from coveralls Jul 27, 2017
Copy link
Member

@tshemsedinov tshemsedinov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose to rename events:
sentMessage -> outgoingMessage
receivedMessage -> incomingMessage

Copy link
Member

@nechaido nechaido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

test.plan(2);

server.getClients()[0].on('heartbeat', (message) => {
test.strictSame(message, {}, 'Heartbeat message must match on server side');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should decapitalize "Heartbeat" here.

test.strictSame(message, {}, 'Heartbeat message must match on server side');
});
connection.on('heartbeat', (message) => {
test.strictSame(message, {}, 'Heartbeat message must match on client side');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well.

Copy link
Member

@tshemsedinov tshemsedinov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after message renaming

Copy link
Member

@belochub belochub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

belochub pushed a commit that referenced this pull request Jul 29, 2017
Fixes: #250
PR-URL: #252
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Dmytro Nechai <nechaido@gmail.com>
Reviewed-By: Timur Shemsedinov <timur.shemsedinov@gmail.com>
Reviewed-By: Mykola Bilochub <nbelochub@gmail.com>
@belochub
Copy link
Member

Landed in 04ed72e.

@belochub belochub closed this Jul 29, 2017
@belochub belochub deleted the add-conn-events branch July 29, 2017 22:41
belochub pushed a commit that referenced this pull request Jan 22, 2018
Fixes: #250
PR-URL: #252
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Dmytro Nechai <nechaido@gmail.com>
Reviewed-By: Timur Shemsedinov <timur.shemsedinov@gmail.com>
Reviewed-By: Mykola Bilochub <nbelochub@gmail.com>
belochub pushed a commit that referenced this pull request Jan 22, 2018
Fixes: #250
PR-URL: #252
Reviewed-By: Alexey Orlenko <eaglexrlnk@gmail.com>
Reviewed-By: Dmytro Nechai <nechaido@gmail.com>
Reviewed-By: Timur Shemsedinov <timur.shemsedinov@gmail.com>
Reviewed-By: Mykola Bilochub <nbelochub@gmail.com>
belochub added a commit that referenced this pull request Jan 22, 2018
This is a new and shiny first major release for `metarhia-jstp`.
Changes include API refactoring and improvements, implementations of
CLI, sessions, and application versions, native addon build optimizations,
lots of bug fixes, test coverage increase, and other, less notable changes.

This release also denotes the bump of the protocol version to v1.0.
The only difference from the previous version of the protocol is that
"old" heartbeat messages (`{}`) are now deprecated and `ping`/`pong`
messages must be used for this purpose instead.

Notable changes:

 * **src,build:** improve the native module subsystem
   *(Alexey Orlenko)*
   [#36](#36)
   **\[semver-minor\]**
 * **build:** compile in ISO C++11 mode
   *(Alexey Orlenko)*
   [#37](#37)
   **\[semver-minor\]**
 * **build:** improve error handling
   *(Alexey Orlenko)*
   [#40](#40)
   **\[semver-minor\]**
 * **lib:** refactor record-serialization.js
   *(Alexey Orlenko)*
   [#41](#41)
   **\[semver-minor\]**
 * **protocol:** change the format of handshake packets
   *(Alexey Orlenko)*
   [#54](#54)
   **\[semver-major\]**
 * **parser:** remove special case for '\0' literal
   *(Mykola Bilochub)*
   [#68](#68)
   **\[semver-major\]**
 * **client:** drop redundant callback argument
   *(Alexey Orlenko)*
   [#104](#104)
   **\[semver-major\]**
 * **client:** handle errors in connectAndInspect
   *(Alexey Orlenko)*
   [#105](#105)
   **\[semver-major\]**
 * **socket,ws:** use socket.destroy() properly
   *(Alexey Orlenko)*
   [#84](#84)
   **\[semver-major\]**
 * **cli:** add basic implementation
   *(Mykola Bilochub)*
   [#107](#107)
   **\[semver-minor\]**
 * **connection:** fix error handling in optional cbs
   *(Alexey Orlenko)*
   [#147](#147)
   **\[semver-major\]**
 * **lib:** change event signature
   *(Denys Otrishko)*
   [#187](#187)
   **\[semver-major\]**
 * **lib:** add address method to Server
   *(Denys Otrishko)*
   [#190](#190)
   **\[semver-minor\]**
 * **lib:** optimize connection events
   *(Denys Otrishko)*
   [#222](#222)
   **\[semver-major\]**
 * **lib:** refactor server and client API
   *(Denys Otrishko)*
   [#209](#209)
   **\[semver-major\]**
 * **lib,src:** rename term packet usages to message
   *(Denys Otrishko)*
   [#270](#270)
   **\[semver-major\]**
 * **lib:** emit events about connection messages
   *(Denys Otrishko)*
   [#252](#252)
   **\[semver-minor\]**
 * **connection:** make callback method private
   *(Alexey Orlenko)*
   [#306](#306)
   **\[semver-major\]**
 * **lib:** implement sessions
   *(Mykola Bilochub)*
   [#289](#289)
   **\[semver-major\]**
 * **connection:** use ping-pong instead of heartbeat
   *(Dmytro Nechai)*
   [#303](#303)
   **\[semver-major\]**
@belochub belochub mentioned this pull request Jan 22, 2018
belochub added a commit that referenced this pull request Jan 23, 2018
This is a new and shiny first major release for `metarhia-jstp`.
Changes include API refactoring and improvements, implementations of
CLI, sessions, and application versions, native addon build optimizations,
lots of bug fixes, test coverage increase, and other, less notable changes.

This release also denotes the bump of the protocol version to v1.0.
The only difference from the previous version of the protocol is that
"old" heartbeat messages (`{}`) are now deprecated and `ping`/`pong`
messages must be used for this purpose instead.

Notable changes:

 * **src,build:** improve the native module subsystem
   *(Alexey Orlenko)*
   [#36](#36)
   **\[semver-minor\]**
 * **build:** compile in ISO C++11 mode
   *(Alexey Orlenko)*
   [#37](#37)
   **\[semver-minor\]**
 * **build:** improve error handling
   *(Alexey Orlenko)*
   [#40](#40)
   **\[semver-minor\]**
 * **lib:** refactor record-serialization.js
   *(Alexey Orlenko)*
   [#41](#41)
 * **parser:** fix a possible memory leak
   *(Alexey Orlenko)*
   [#44](#44)
   **\[semver-minor\]**
 * **protocol:** change the format of handshake packets
   *(Alexey Orlenko)*
   [#54](#54)
   **\[semver-major\]**
 * **parser:** make parser single-pass
   *(Mykola Bilochub)*
   [#61](#61)
 * **parser:** remove special case for '\0' literal
   *(Mykola Bilochub)*
   [#68](#68)
   **\[semver-major\]**
 * **parser:** fix bug causing node to crash
   *(Mykola Bilochub)*
   [#75](#75)
 * **client:** drop redundant callback argument
   *(Alexey Orlenko)*
   [#104](#104)
   **\[semver-major\]**
 * **client:** handle errors in connectAndInspect
   *(Alexey Orlenko)*
   [#105](#105)
   **\[semver-major\]**
 * **socket,ws:** use socket.destroy() properly
   *(Alexey Orlenko)*
   [#84](#84)
   **\[semver-major\]**
 * **cli:** add basic implementation
   *(Mykola Bilochub)*
   [#107](#107)
   **\[semver-minor\]**
 * **connection:** fix error handling in optional cbs
   *(Alexey Orlenko)*
   [#147](#147)
   **\[semver-major\]**
 * **test:** add JSON5 specs test suite
   *(Alexey Orlenko)*
   [#158](#158)
 * **lib:** change event signature
   *(Denys Otrishko)*
   [#187](#187)
   **\[semver-major\]**
 * **lib:** add address method to Server
   *(Denys Otrishko)*
   [#190](#190)
   **\[semver-minor\]**
 * **parser:** implement NaN and Infinity parsing
   *(Mykola Bilochub)*
   [#201](#201)
 * **parser:** improve string parsing performance
   *(Mykola Bilochub)*
   [#220](#220)
 * **lib:** optimize connection events
   *(Denys Otrishko)*
   [#222](#222)
   **\[semver-major\]**
 * **lib:** refactor server and client API
   *(Denys Otrishko)*
   [#209](#209)
   **\[semver-major\]**
 * **lib,src:** rename term packet usages to message
   *(Denys Otrishko)*
   [#270](#270)
   **\[semver-major\]**
 * **lib:** emit events about connection messages
   *(Denys Otrishko)*
   [#252](#252)
   **\[semver-minor\]**
 * **lib:** implement API versioning
   *(Denys Otrishko)*
   [#231](#231)
   **\[semver-minor\]**
 * **lib:** allow to set event handlers in application
   *(Denys Otrishko)*
   [#286](#286)
   **\[semver-minor\]**
 * **lib:** allow to broadcast events from server
   *(Denys Otrishko)*
   [#287](#287)
   **\[semver-minor\]**
 * **connection:** make callback method private
   *(Alexey Orlenko)*
   [#306](#306)
   **\[semver-major\]**
 * **lib:** implement sessions
   *(Mykola Bilochub)*
   [#289](#289)
   **\[semver-major\]**
 * **connection:** use ping-pong instead of heartbeat
   *(Dmytro Nechai)*
   [#303](#303)
   **\[semver-major\]**
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants