Skip to content

Conversation

@ballinette
Copy link

@ballinette ballinette commented Aug 11, 2017

Improvements

  • Refactor the network wrappers to improve separation of concerns:

    • simplification of network states (offline, connecting, connected for realtime protocole ; offline, ready for future HTTP protocol)
    • each protocol is responsible of its states, and manage itself the offline mode
    • Kuzzle object still exposes queuing methods, but now delegates their implementation to network protocols.
  • Refactor the Room management : the Room class now inherits from EventEmitter:

    • a room handles the subscription to Kuzzle API (one single subscription for each room, with its own filters and options)
    • listener callbacks can subscribe to a room to be notified by Kuzzle notifications.

Some sample codes to manage rooms:

var 
  collection = kuzzle.collection('foo', 'bar'),
  filters = {equals: {foo: 'bar'}},
  room;

/*
* simple subscribe to new document with default scope/state options
*/
room = collection.subscribe(filters, function(data) {
  console.log('New document within the scope: ', data.document);
}).onDone(function(err, res) {
  if (err) {
    console.error('Error while subscribing to the room: ', err);
  } else {
    console.log('Subscription ready');
  }
});

/*
* Create a Room with custom options and add some listeners to it
*/

// create the room:
room = collection.room(filters, {state: all, scope: all, users: all, subscribeToSelf: false});

// listen to notifications about documents:
room.on('document', function(data) {
  if (data.scope === 'in') {
    console.log('New document within the scope: ', data.document);
  } else if (data.scope === 'out') {
    console.log('Document moved from the scope: ', data.document);
  } 
});

// listen to notifications about other users subscribing to the same room:
room.on('user', function(data) {
  if (data.user === 'in') {
    console.log('A user has joigned the room', data.volatile);
  } else if (data.user == 'out') {
    console.log('A user has leaved the room', data.volatile);
  }
  console.log('Number of listening users: ', data.result.count);
});

// subscribe to the room:
room.subscribe(function(err, res) {
  if (err) {
    console.error('Error while subscribing to the room: ', err);
  } else {
    console.log('Subscription ready');
  }
});

Boyscout improvements

  • use ES6 and Babel to browser transpilation (only for new and refactored classes for now)
  • promisify somme missing method of Kuzzle and Room prototypes
  • replace jwtToken by jwt
  • improve unit tests

Breaking changes

Renamed properties and method in Kuzzle prototype

  • jwtToken => jwt
  • getJwtToken() => getJwt()
  • setJwtToken(token)' => setJwt(token)`
  • unsetJwtToken() => unsetJwt()
  • replayQueue() => playQueue()

Removal of SubscribeResult prototype:

  • onDone method move to Room prototype.
  • Collection.subscribte() method returns now the created Room object

Changed signature for Collection.room method and Room constructor

collection.room([options]) => collection.room(filters, [options])
new Room(collection, [options]) => new Room(collection, filters, [options])

Changed signature for Room.renew method

renew([filters], notificationCallback, subscriptionCallback) => renew(subscriptionCallback)

  • filters is now an immutable property (we need to create a new Room if we want to change the filters)
  • notificationCallback has become useless since the Room is now an event emitter:
// Old code:
room.renew(notificationCallback, subscriptionCallback);

// ===> New Code:
room.renew(subscriptionCallback).addListener('document', notificationCalllback);

New option protocol to Kuzzle constructor

Must be filled to use another protocol than native websocket
currently, 2 supported values:

  • websocket (default)
  • socketio
    ⚠️ The network wrappers does not automatically fallback to socketIO anymore if Websocket is not supported.

@codecov-io
Copy link

codecov-io commented Aug 11, 2017

Codecov Report

Merging #243 into 6.x will increase coverage by 0.31%.
The diff coverage is 99.55%.

Impacted file tree graph

@@            Coverage Diff             @@
##              6.x     #243      +/-   ##
==========================================
+ Coverage   98.27%   98.58%   +0.31%     
==========================================
  Files          17       17              
  Lines        2149     2127      -22     
  Branches      611      615       +4     
==========================================
- Hits         2112     2097      -15     
+ Misses         37       30       -7
Impacted Files Coverage Δ
src/eventEmitter/index.js 92.47% <100%> (ø) ⬆️
src/networkWrapper/index.js 100% <100%> (ø) ⬆️
src/networkWrapper/protocols/websocket.js 100% <100%> (ø)
src/Room.js 100% <100%> (ø) ⬆️
src/Collection.js 100% <100%> (+1.95%) ⬆️
src/networkWrapper/protocols/socketio.js 100% <100%> (ø)
src/Kuzzle.js 98.52% <98.88%> (-0.25%) ⬇️
src/networkWrapper/protocols/abstract/realtime.js 99.29% <99.29%> (ø)
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update db3108f...9b81c95. Read the comment docs.


this.kuzzle.callbackRequired('Collection.scrollSpecifications', cb);

if (options && options.scroll) {
Copy link
Author

@ballinette ballinette Aug 11, 2017

Choose a reason for hiding this comment

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

Note: not needed here since scroll option is already managed within kuzzle.querymethod


request.scrollId = scrollId;

if (options && options.scroll) {
Copy link
Author

@ballinette ballinette Aug 11, 2017

Choose a reason for hiding this comment

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

Note: not needed here since scroll option is already managed within kuzzle.querymethod


if (!listeners || !listeners.length) {
return;
return false;
Copy link
Author

@ballinette ballinette Aug 18, 2017

Choose a reason for hiding this comment

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

Note: fix KuzzleEventEmitter methods signatures, to be consistant with NodeJS event specitications (emit should return a boolean value - see https://nodejs.org/api/events.html#events_emitter_emit_eventname_args )

Copy link
Contributor

@scottinet scottinet left a comment

Choose a reason for hiding this comment

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

A few nitpickings here and there, but apart from that this looks good to me. Though I have a hard time to figure out how all this will play together. I trust you on that :-)

src/Kuzzle.js Outdated
object.jwt = this.jwt;
}

if (room.volatile) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This entire if block and the sdkVersion assignment below can be replaced with this one-liner:

Object.assign(object.volatile, room.volatile, {sdkVersion: this.sdkVersion});

(Object.assign will ignore undefined values so it's safe to use without testing for the existence of this object inside room)

Copy link
Author

Choose a reason for hiding this comment

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

done

object.jwt = this.jwt;
}

if (room.volatile) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

src/Kuzzle.js Outdated
self.network.onConnectError(function (error) {
var connectionError = new Error('Unable to connect to kuzzle proxy server at "' + self.host + ':' + self.port + '"');
this.network.addListener('networkError', function (error) {
var connectionError = new Error('Unable to connect to kuzzle proxy server at "' + self.network.host + ':' + self.network.port + '"');
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking 1: use const instead of var
Nitpicking 2: use template litterals :-)

src/Room.js Outdated
return this.kuzzle.bluebird.promisifyAll(this, {
suffix: 'Promise',
filter: function (name, func, target, passes) {
var whitelist = ['count', 'renew', 'subscribe', 'unsubscribe', 'onDone'];
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking: use const instead of var

src/Room.js Outdated
* @param {responseCallback} cb - Handles the query response
*/
count(cb) {
var data;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking: use const instead of var ( data can be declared directly line 119 instead of here)

src/Room.js Outdated
* @return {*} this
*/
renew(cb) {
var
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking: use const instead of var

* Clean history from requests made more than 10s ago
*/
function cleanHistory (requestHistory) {
var
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking: consider using const instead of var.

var
now = Date.now();

Object.keys(requestHistory).forEach(function (key) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking: replace with for(const ... of ...)

var reason = message;
this.client.onclose = (closeEvent, message) => {
let
error,
Copy link
Contributor

Choose a reason for hiding this comment

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

This error variable is shadowed by the one declared in the function starting line 65.

Suggestion: declare this variable as a const directly line 58, as it seems to be the only block where it is used.

this.client.onerror = function (error) {
this.client.onerror = error => {
if (!(error instanceof Error)) {
error = new Error(error);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking: function parameters should not be overwritten.

@ballinette ballinette force-pushed the refactor-network-wrappers branch from 6bdd4c5 to 0b5979a Compare August 22, 2017 14:56
ballinette added 5 commits August 29, 2017 19:03
@ballinette ballinette force-pushed the refactor-network-wrappers branch from 4ff1148 to dab1ecc Compare August 29, 2017 17:03
}
return new (require('./protocols/websocket'))(host, options);
case 'socketio':
if (!window.io) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We assume that no one will ever try to use Socket.IO outside a browser?
(after all, sounds fair to me, just asking to be sure it's on purpose)

Copy link
Author

Choose a reason for hiding this comment

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

If we are outside a browser, we have native websocket support, so I don't see any reason to use socketIO...

});

it('should dequeue requests automatically on a connection success', function (done) {
it('should keep a valid JWT Token at reconnection', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

a valid JWT ?


describe('=> on reconnection', function () {
it('should exit offline mode when reconnecting', function (done) {
it('should empty the JWT Token at reconnection if it has expired', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

JWT ?

should((function () {kuzzle.setDefaultIndex(null);})).throw();
should((function () {kuzzle.setDefaultIndex(undefined);})).throw();
describe('#getJwt', function () {
it('should return the current jwt token', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

JWT

});
should(kuzzle.jwt).be.undefined();
should(loginAttemptStub).be.calledOnce();
should(loginAttemptStub).be.calledWith({ error: 'Cannot find a valid JWT token in the following object: {"foo":"bar"}', success: false });
Copy link
Contributor

Choose a reason for hiding this comment

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

:(

Copy link
Contributor

@xbill82 xbill82 left a comment

Choose a reason for hiding this comment

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

Ok for me!

@ballinette ballinette force-pushed the refactor-network-wrappers branch from ea2e97d to 7b767e7 Compare September 14, 2017 16:55
# Conflicts:
#	src/Kuzzle.js
#	test/network/networkWrapper.test.js
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