Skip to content

Commit

Permalink
Merge pull request #129 from denis-vanat/feature/serializer
Browse files Browse the repository at this point in the history
Feature/serializer
  • Loading branch information
alevy authored Oct 5, 2020
2 parents e9a2216 + e1ec06d commit 94aedaa
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 7 deletions.
48 changes: 41 additions & 7 deletions lib/memjs/memjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var errors = require('./protocol').errors;
var Server = require('./server').Server;
var noopSerializer = require('./noop-serializer').noopSerializer;
var makeRequestBuffer = require('./utils').makeRequestBuffer;
var hashCode = require('./utils').hashCode;
var merge = require('./utils').merge;
Expand All @@ -15,6 +16,8 @@ var Client = function(servers, options) {
this.seq = 0;
this.options = merge(options || {},
{failoverTime: 60, retries: 2, retry_delay: 0.2, expires: 0, logger: console});

this.serializer = this.options.serializer || noopSerializer;
};

// Creates a new client given an optional config string and optional hash of
Expand Down Expand Up @@ -42,6 +45,20 @@ var Client = function(servers, options) {
// ~~~~
//
// Defaults to `console`.
// * `serializer` - the object which will (de)serialize the data. It needs
// two public methods: serialize and deserialize. It defaults to the
// noopSerializer:
//
// ~~~~
// var noopSerializer = {
// serialize: function (opcode, value, extras) {
// return { value: value, extras: extras };
// },
// deserialize: function (opcode, value, extras) {
// return { value: value, extras: extras };
// }
// };
// ~~~~
//
// Or options for the servers including:
// * `username` and `password` for fallback SASL authentication credentials.
Expand Down Expand Up @@ -118,8 +135,8 @@ var promisify = function(command) {
// _value_ and _flags_ are both `Buffer`s. If the key is not found, the
// callback is invoked with null for both arguments and no error.
Client.prototype.get = function(key, callback) {
var self = this;
if(callback === undefined) {
var self = this;
return promisify(function(callback) {
self.get(key, function(err, value, flags) {
callback(err, {value: value, flags: flags});
Expand All @@ -136,7 +153,10 @@ Client.prototype.get = function(key, callback) {
}
switch (response.header.status) {
case 0:
if (callback) { callback(null, response.val, response.extras); }
if (callback) {
var deserialized = self.serializer.deserialize(response.header.opcode, response.val, response.extras);
callback(null, deserialized.value, deserialized.extras);
}
break;
case 1:
if (callback) { callback(null, null, null); }
Expand Down Expand Up @@ -182,7 +202,10 @@ Client.prototype.set = function(key, value, options, callback) {
this.incrSeq();
var expiration = makeExpiration(expires || this.options.expires);
var extras = Buffer.concat([Buffer.from('00000000', 'hex'), expiration]);
var request = makeRequestBuffer(1, key, extras, value, this.seq);

var opcode = 1;
var serialized = this.serializer.serialize(opcode, value, extras);
var request = makeRequestBuffer(opcode, key, serialized.extras, serialized.value, this.seq);
this.perform(key, request, this.seq, function(err, response) {
if (err) {
if (callback) { callback(err, null); }
Expand Down Expand Up @@ -234,7 +257,10 @@ Client.prototype.add = function(key, value, options, callback) {
this.incrSeq();
var expiration = makeExpiration(expires || this.options.expires);
var extras = Buffer.concat([Buffer.from('00000000', 'hex'), expiration]);
var request = makeRequestBuffer(2, key, extras, value, this.seq);

var opcode = 2;
var serialized = this.serializer.serialize(opcode, value, extras);
var request = makeRequestBuffer(opcode, key, serialized.extras, serialized.value, this.seq);
this.perform(key, request, this.seq, function(err, response) {
if (err) {
if (callback) { callback(err, null, null); }
Expand Down Expand Up @@ -289,7 +315,10 @@ Client.prototype.replace = function(key, value, options, callback) {
this.incrSeq();
var expiration = makeExpiration(expires || this.options.expires);
var extras = Buffer.concat([Buffer.from('00000000', 'hex'), expiration]);
var request = makeRequestBuffer(3, key, extras, value, this.seq);

var opcode = 3;
var serialized = this.serializer.serialize(opcode, value, extras);
var request = makeRequestBuffer(opcode, key, serialized.extras, serialized.value, this.seq);
this.perform(key, request, this.seq, function(err, response) {
if (err) {
if (callback) { callback(err, null, null); }
Expand Down Expand Up @@ -485,7 +514,9 @@ Client.prototype.append = function(key, value, callback) {
// TODO: support version (CAS)
var logger = this.options.logger;
this.incrSeq();
var request = makeRequestBuffer(0x0E, key, '', value, this.seq);
var opcode = 0x0E;
var serialized = this.serializer.serialize(opcode, value, '');
var request = makeRequestBuffer(opcode, key, serialized.extras, serialized.value, this.seq);
this.perform(key, request, this.seq, function(err, response) {
if (err) {
if (callback) { callback(err, null); }
Expand Down Expand Up @@ -521,7 +552,10 @@ Client.prototype.prepend = function(key, value, callback) {
// TODO: support version (CAS)
var logger = this.options.logger;
this.incrSeq();
var request = makeRequestBuffer(0x0E, key, '', value, this.seq);

var opcode = 0x0E;
var serialized = this.serializer.serialize(opcode, value, '');
var request = makeRequestBuffer(opcode, key, serialized.extras, serialized.value, this.seq);
this.perform(key, request, this.seq, function(err, response) {
if (err) {
if (callback) { callback(err, null); }
Expand Down
10 changes: 10 additions & 0 deletions lib/memjs/noop-serializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var noopSerializer = {
serialize: function (opcode, value, extras) {
return { value: value, extras: extras };
},
deserialize: function (opcode, value, extras) {
return { value: value, extras: extras };
}
};

exports.noopSerializer = noopSerializer;
116 changes: 116 additions & 0 deletions test/client_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,45 @@ test('GetNotFound', function(t) {
});
});

test('GetSerializer', function(t) {
var n = 0;
var dn = 0;
var dummyServer = new MemJS.Server();
dummyServer.write = function(requestBuf) {
var request = MemJS.Utils.parseMessage(requestBuf);
t.equal('hello', request.key.toString());
n += 1;
dummyServer.respond(
{header: {status: 0, opaque: request.header.opaque},
val: 'world', extras: 'flagshere'});
};

var client = new MemJS.Client([dummyServer], {
serializer: {
serialize: function(opcode, value, extras){
return { value: value, extras: extras };
},
deserialize: function (opcode, value, extras) {
dn += 1;
return { value: 'deserialized', extras: extras };
}
}
});
var assertor = function(err, val, flags) {
t.equal('deserialized', val);
t.equal('flagshere', flags);
t.equal(null, err);
t.equal(1, n, 'Ensure get is called');
t.equal(1, dn, 'Ensure deserialization is called once');
};
client.get('hello', assertor);
n = 0;
dn = 0;
return client.get('hello').then(function(res) {
assertor(null, res.value, res.flags);
});
});

test('SetSuccessful', function(t) {
var n = 0;
var dummyServer = new MemJS.Server();
Expand Down Expand Up @@ -242,6 +281,43 @@ test('SetUnicode', function(t) {
});
});

test('SetSerialize', function(t) {
var n = 0;
var sn = 0;
var dummyServer = new MemJS.Server();
dummyServer.write = function(requestBuf) {
var request = MemJS.Utils.parseMessage(requestBuf);
t.equal('hello', request.key.toString());
t.equal('serialized', request.val.toString());
n += 1;
dummyServer.respond({header: {status: 3, opaque: request.header.opaque}});
};

var client = new MemJS.Client([dummyServer], {
serializer: {
serialize: function(opcode, value, extras){
sn += 1;
return { value: 'serialized', extras: extras };
},
deserialize: function (opcode, value, extras) {
return { value: value, extras: extras };
}
}
});
var assertor = function(err, val) {
t.equal(null, val);
t.equal('MemJS SET: ' + errors[3], err.message);
t.equal(1, n, 'Ensure set is called');
t.equal(1, sn, 'Ensure serialization is called once');
};
client.set('hello', 'world', {}, assertor);
n = 0;
sn = 0;
return client.set('hello', 'world', {}).catch(function(err) {
assertor(err, null);
});
});

test('AddSuccessful', function(t) {
var n = 0;
var dummyServer = new MemJS.Server();
Expand Down Expand Up @@ -308,6 +384,46 @@ test('AddKeyExists', function(t) {
});
});

test('AddSerializer', function(t) {
var n = 0;
var sn = 0;
var dummyServer = new MemJS.Server();
dummyServer.write = function(requestBuf) {
var request = MemJS.Utils.parseMessage(requestBuf);
t.equal('hello', request.key.toString());
t.equal('serialized', request.val.toString());
t.equal('0000000100000400', request.extras.toString('hex'));
n += 1;
dummyServer.respond({header: {status: 0, opaque: request.header.opaque}});
};

var client = new MemJS.Client([dummyServer], {
expires: 1024,
serializer: {
serialize: function(opcode, value, extras){
sn += 1;
extras.writeUInt32BE(1, 0);
return { value: 'serialized', extras: extras };
},
deserialize: function (opcode, value, extras) {
return { value: value, extras: extras };
}
}
});
var assertor = function(err, val) {
t.equal(null, err);
t.equal(true, val);
t.equal(1, n, 'Ensure add is called');
t.equal(1, sn, 'Ensure serialization is called once');
};
client.add('hello', 'world', {}, assertor);
n = 0;
sn = 0;
return client.add('hello', 'world', {}).then(function(success) {
assertor(null, success);
});
});

test('ReplaceSuccessful', function(t) {
var n = 0;
var dummyServer = new MemJS.Server();
Expand Down

0 comments on commit 94aedaa

Please sign in to comment.