Skip to content

Commit

Permalink
functionnal alpha build + benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
fed135 committed Mar 29, 2016
1 parent d0cc8e9 commit b722d8d
Show file tree
Hide file tree
Showing 23 changed files with 369 additions and 100 deletions.
53 changes: 41 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
[![Kalm](https://img.shields.io/npm/v/kalm.svg)](https://www.npmjs.com/package/kalm)
[![Build Status](https://travis-ci.org/fed135/Kalm.svg?branch=master)](https://travis-ci.org/fed135/Kalm)
[![Code Climate](https://codeclimate.com/github/fed135/Kalm/badges/gpa.svg)](https://codeclimate.com/github/fed135/Kalm)
[![Dependencies status](https://david-dm.org/fed135/Kalm.svg)](https://www.npmjs.com/package/kalm)
[![Dependencies Status](https://david-dm.org/fed135/Kalm.svg)](https://www.npmjs.com/package/kalm)
[![Current Stage](https://img.shields.io/badge/stage-alpha-blue.svg)](https://codeclimate.com/github/fed135/Kalm)


[!!!Early Dev Stage!!!]

A library to simplify and optimize your Socket communications.

- Packet bundling
- Packet minification
- Easy-to-use single syntax for all protocols
- Multiplexing for everyone!
- Channels for all protocols
- Plug-and-play
- Ultra-flexible and extensible


## Adapters
Expand All @@ -22,9 +23,9 @@ Allow you to easily use different socket types, hassle-free

| **Type** | **Library used** | **Status** |
|---|---|---|
| IPC | | IN-DEV |
| TCP | | - |
| UDP | | - |
| IPC | | STABLE |
| TCP | | STABLE |
| UDP | | DEV |


## Encoders
Expand All @@ -33,8 +34,8 @@ Encode the payloads before emitting.

| **Type** | **Library used** | **Status** |
|---|---|---|
| JSON | | PROD |
| MSG-PACK | [msgpack-lite](https://github.com/kawanet/msgpack-lite) | PROD |
| JSON | | STABLE |
| MSG-PACK | [msgpack-lite](https://github.com/kawanet/msgpack-lite) | STABLE |


## Middleware
Expand All @@ -43,7 +44,7 @@ Perform batch operation of payloads.

| **Type** | **Library used** | **Status** |
|---|---|---|
| Bundler | | IN-DEV |
| Bundler | | STABLE |

---

Expand Down Expand Up @@ -82,8 +83,28 @@ The framework is flexible enough so that you can load your own custom adapters,

## Performance analysis

// TODO

### Requests per minute

| | IPC | TCP | UDP |
|---|---|---|---|
| Raw | 1332330 | 844750 | - |
| Kalm | 5558920 | 1102570 | - |
| **Result** | +417.2% | +30.5% | - |

*Benchmarks based on a single-thread queue test with default settings*

*5 runs average*

### Bytes transfered

| | IPC | TCP | UDP |
|---|---|---|---|
| Raw | N/A | 81000 | - |
| Kalm | N/A | 6759 | - |
| **Result** | N/A | 11.9x less | |

*Using wireshark - number of bytes transfered per **1000** requests*
*I estimate a very decent decrease in overhead bytes on IPC too, haven't found a way to put a number on it, though.

## Installation

Expand All @@ -107,3 +128,11 @@ Ex:
## Roadmap

[Milestones](https://github.com/fed135/Kalm/milestones)


## Contributing

I am looking for contributors to help improve the codebase and create adapters, encoders and middleware.
Email me for details.

Thank you!
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "kalm",
"version": "0.0.1",
"version": "0.1.0",
"description": "The socket optimizer",
"main": "./index.js",
"scripts": {
"test": "mocha tests/unit/index.js"
"test": "mocha tests/index.js"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -33,9 +33,9 @@
"homepage": "https://github.com/fed135/Kalm#readme",
"devDependencies": {
"chai": "3.4.x",
"mocha": "2.4.x",
"coveralls": "2.11.x",
"istanbul": "0.4.x"
"istanbul": "0.4.x",
"mocha": "2.4.x"
},
"dependencies": {
"debug": "2.2.x",
Expand Down
11 changes: 5 additions & 6 deletions src/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ function Client(socket, options) {
// Transformations (middleware)
transform: options.transform || {
bundler: {
maxPackets: 100,
delay: (1000/128)
maxPackets: 512,
delay: 16
}
}
};
Expand All @@ -64,8 +64,7 @@ function Client(socket, options) {
}

// Socket object
if (socket) this.socket = socket;
else this.socket = this._createSocket();
this.socket = this._createSocket(socket);

// Data packets - transient state - by channel
this.packets = {};
Expand Down Expand Up @@ -115,8 +114,8 @@ Client.prototype.send = function(channel, payload) {
middleware.process(this, channel, payload);
};

Client.prototype._createSocket = function() {
return adapters.resolve(this.options.adapter).createSocket(this);
Client.prototype._createSocket = function(socket) {
return adapters.resolve(this.options.adapter).createSocket(this, socket);
};

Client.prototype._emit = function(channel) {
Expand Down
11 changes: 8 additions & 3 deletions src/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ Server.prototype.listen = function(callback) {
}
};

Server.prototype.channel = function(name, handler) {
this.channels[name] = handler;
};

Server.prototype.broadcast = function(channel, payload) {
for (var i = this.connections.length - 1; i >= 0; i--) {
this.connections[i].send(channel, payload);
Expand All @@ -67,9 +71,11 @@ Server.prototype._handleLift = function() {
this.emit('ready');
};

Server.prototype.stop = function() {
Server.prototype.stop = function(callback) {
this.connections.length = 0;
if (this.listener) this.listener.stop();
if (this.listener) {
adapters.resolve(this.options.adapter).stop(this, callback);
}
};

Server.prototype._handleRequest = function(socket) {
Expand All @@ -78,7 +84,6 @@ Server.prototype._handleRequest = function(socket) {
encoder: this.options.encoder,
channels: this.channels
});
socket.on('data', client._handleRequest.bind(client));
this.connections.push(client);
this.emit('connection', client);
};
Expand Down
19 changes: 16 additions & 3 deletions src/adapters/ipc.adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ function listen(server, callback) {
fs.unlink(defaultPath + server.options.port, function _bindSocket() {
server.listener = net.createServer(server._handleRequest.bind(server));
server.listener.listen(defaultPath + server.options.port, callback);
server.listener.on('error', function _handleServerError(err) {
server.emit('error', err);
});
});
};

function stop(server, callback) {
server.listener.close(callback || function() {});
}

/**
* Sends a message with a socket client, then pushes it back to its peer
* @method send
Expand All @@ -46,9 +53,14 @@ function send(socket, payload) {
* @param {Kalm.Client} client The client to create the socket for
* @returns {Socket} The created ipc socket
*/
function createSocket(client) {
var socket = net.connect(defaultPath + client.options.port);
function createSocket(client, socket) {
if (!socket) {
socket = net.connect(defaultPath + client.options.port);
}
socket.on('data', client._handleRequest.bind(client));
socket.on('error', function _handleSocketError(err) {
client.emit('error', err);
});

return socket;
};
Expand All @@ -58,5 +70,6 @@ function createSocket(client) {
module.exports = {
listen: listen,
send: send,
createSocket: createSocket
createSocket: createSocket,
stop: stop
};
75 changes: 32 additions & 43 deletions src/adapters/tcp.adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,19 @@ var net = require('net');

/* Methods -------------------------------------------------------------------*/

/**
* TCP adapter
* @constructor
* @param {Kalm} K The Kalm instance
*/
function TCP(options, handler) {
this.options = options;
this.handler = handler;
this.server = null;
}

/**
* Listens for tcp connections on the selected port.
* @method listen
* @memberof TCP
* @param {function} callback The success callback for the operation
*/
TCP.prototype.listen = function(callback) {
this.server = net.createServer(this.handler)
.listen(this.options.port, callback);
};
function listen(server, callback) {
server.listener = net.createServer(server._handleRequest.bind(server));
server.listener.listen(server.options.port, callback);
server.listener.on('error', function _handleServerError(err) {
server.emit('error', err);
});
}

/**
* Sends a message with a socket client
Expand All @@ -42,42 +34,39 @@ TCP.prototype.listen = function(callback) {
* @param {Socket} socket The socket to use
* @param {function|null} callback The callback method
*/
TCP.prototype.send = function(payload, socket, callback) {
socket.write(payload, callback);
};
function send(socket, payload) {
console.log('write');
socket.write(payload);
}

function stop(server, callback) {
server.listener.close(callback || function() {});
}

/**
* Creates a client
* @method createClient
* @method createSocket
* @memberof TCP
* @param {Client} client The client to create the socket for
* @returns {Socket} The created tcp client
*/
TCP.prototype.createClient = function(client) {
return net.connect(this.options.port);
};
function createSocket(client, socket) {
if (!socket) {
socket = net.connect(client.options.port, client.options.hostname);
}
socket.on('data', client._handleRequest.bind(client));
socket.on('error', function _handleSocketError(err) {
client.emit('error', err);
});

/**
* Calls the disconnect method on a socket
* @method removeClient
* @memberof TCP
* @param {Socket} socket The socket to disconnect
*/
TCP.prototype.removeClient = function(socket) {
socket.disconnect();
};

/**
* Stops listening for ipc connections and closes the server
* @method stop
* @memberof TCP
* @param {function|null} callback The callback method
*/
TCP.prototype.stop = function(callback) {
if (this.server) this.server.close(callback);
else callback();
};
return socket;
}

/* Exports -------------------------------------------------------------------*/

module.exports = TCP;
module.exports = {
listen: listen,
send: send,
createSocket: createSocket,
stop: stop
};
Loading

0 comments on commit b722d8d

Please sign in to comment.