GithubHelp home page GithubHelp logo

memcachier / memjs Goto Github PK

View Code? Open in Web Editor NEW
195.0 12.0 52.0 643 KB

A memcache client for node using the binary protocol and SASL authentication

License: MIT License

JavaScript 100.00%
memcache memcached memcached-clients

memjs's Introduction

MemJS

npm Build Status Gitter

MemJS is a pure Node.js client library for using memcache, in particular, the MemCachier service. It uses the binary protocol and support SASL authentication.

Documentation can be found here: https://memjs.netlify.com/

TOC

  1. Requirements
  2. Installation
  3. Configuration
  4. Usage
  5. How to help

Requirements

Supported Node.js versions

MemJS is tested to work with version 0.10 or higher of Node.js.

Installation

MemJS is available from the npm registry:

$ npm install memjs

To install from git:

$ git clone git://github.com/alevy/memjs.git
$ cd memjs
$ npm link

MemJS was designed for the MemCachier memcache service but will work with any memcache server that speaks the binary protocol. Many software repositories have a version of memcached available for installation:

Ubuntu

$ apt-get install memcached

OS X

$ brew install memcached

Configuration

MemJS understands the following environment variables:

  • MEMCACHIER_SERVERS - used to determine which servers to connect to. Should be a comma separated list of [hostname:port].
  • MEMCACHIER_USERNAME - if present with MEMCACHIER_PASSWORD, MemJS will try to authenticated to the server using SASL.
  • MEMCACHIER_PASSWORD - if present with MEMCACHIER_USERNAME, MemJS will try to authenticated to the server using SASL.
  • MEMCACHE_USERNAME - used if MEMCACHIER_USERNAME is not present
  • MEMCACHE_PASSWORD - used if MEMCACHIER_PASSWORD is not present

Environment variables are only used as a fallback for explicit parameters.

Usage

You can start using MemJS immediately from the node console:

$ var memjs = require('memjs')
$ var client = memjs.Client.create()
$ client.get('hello', function(err, val) { console.log(val); })

If callbacks are not specified, the command calls return promises.

Settings Values

client.set('hello', 'world', {expires:600}, function(err, val) {

});

The set(key, val, options, callback) function accepts the following parameters.

  • key: key to set
  • val: value to set
  • options: an object of options. Currently supports only the key expires, which is a time interval, in seconds, after which memcached will expire the object
  • callback: a callback invoked after the value is set
    • err : error
    • val : value retrieved

Getting Values

client.get('hello', function(err, val) {

});

The get(key, callback) function accepts the following parameters.

Note that values are always returned as Buffers, regardless of whether a Buffer or String was passed to set.

  • key: key to retrieve
  • callback: a callback invoked after the value is retrieved
    • err : error
    • val : value retrieved as a Buffer

Contributing

The best way to contribute to the project is by reporting bugs and testing unpublished versions. If you have a staging or development app, the easiest way to do this is using the git repository as your memjs package dependency---in package.json:

{
  "name": "MyAppName",
  ...
  "dependencies": {
    ...
    "memjs": "git://github.com/alevy/memjs.git#master"
    ...
  }
}

If you find a bug, please report as an issue. If you fix it, please don't hesitate to send a pull request on GitHub or via e-mail.

Feature suggestions are also welcome! These includes suggestions about syntax and interface design.

Finally, a great way to contribute is to implement a feature that's missing and send a pull request. The list below contains some planned features that have not been addressed yet. You can also implement a feature not a list if you think it would be good.

TODOS

  • Support flags
  • Support multi commands
  • Support CAS
  • Consistent hashing for keys and/or pluggable hashing algorithm

Copyright

Copyright (c) 2012 Amit Levy, MemCachier. See LICENSE for details.

memjs's People

Contributors

adamloving avatar alevy avatar amywilkie avatar apendleton avatar dblock avatar dependabot[bot] avatar dterei avatar flippmoke avatar javatutorials2016 avatar jfred avatar kawanet avatar liamdon avatar lucasbcoelho avatar miccolis avatar nbransby avatar olemstrom avatar ovidiusabou avatar psilva261 avatar safeer avatar saschat avatar shokai avatar shudrum avatar sparkida avatar vanatd avatar vikaash02 avatar voxpelli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memjs's Issues

read buffer length error

in header.js I found this code:

...
dataType: headerBuf.readUInt8(6),
...

I think the length parameter should be 5 not 6.

Hangs if server is down and multiple concurrent get requests made

I have a list of objects and I'm trying to fetch values for them from my cache in parallel. Something like:

async = require 'async'

serialize = (obj, done) ->
    cache.get obj.user, (err, cached) ->
        obj.avatar = cached.avatar
        done err, obj

async.map myList, serialize, (err, results) ->
    return res.send(err) if err?
    res.send 200, results

The problem is, that if no connection has been made (the memcached instance/memcachier server is unavailable), then the first get call works, but the subsequent ones never have the callback fired. I've been trying to write a test to reproduce, but I'm not sure if it's possible with your test setup. Whenever I try to make the Dummy Server async (just wrapping in a setTimeout call) everything hangs...

Is this a known issue? Could it have something to do with the error handler/listeners? I see there was a concurrency fork of this project, but it's out of date. Also, I switched to mc module and everything works fine locally, but it does not support SASL, and fails with memcachier. Thoughts???

Problems with Mac OS

Installed memcached-win64-1.4.4-14 under Windows - not any problem with node 0.8.8.
Basically, this thing works:

var memjs = require("memjs");
var client = memjs.Client.create();
client.add("key", "value", function(a,b,c){
console.log("write");
client.get("key", function(a,b,c){
console.log(b.toString());
client.close();
});
});

With Mac OS 10.6.8 and node 0.8.8, same script, memcached installed with brew, nothing:
admin$ node memjs.js

timers.js:103
if (!process.listeners('uncaughtException').length) throw e;
^
Error: socket timed out.
at Socket.Server.sock.waiting (/Users/admin/node_modules/memjs/lib/memjs/server.js:122:28)
at Socket.g (events.js:185:14)
at Socket.EventEmitter.emit (events.js:85:17)
at Socket._onTimeout (net.js:186:8)
at Timer.list.ontimeout (timers.js:101:19)

Memcached is there, if I launch it with -vv I can succesfully telnet it and do stuff (and I can see that the connection starts and ends when my node script is executed)

I tried to make the timeout longer, but it doesn't matter, actually seems like this event is never fired on server.js line 103:
this.on('data', function(dataBuf) {
waiting = false;
self.responseHandler(dataBuf)
});

Any clues? Happy to provide more details and contribute if needed?
Thanks

UPDATE DOCS

Pleas update docs to say it defaults to localhost.

I just added code to do this. Now deleted it. wasted time! :D

Anomalas error with multiple nodes

Another one for today. If I have time, I'll look at in more detail:

In a heroku deployment of my app, connecting to MemCachier, I encountered the following error:

ERROR { [TypeError: Cannot read property 'quiet' of undefined]
2013-01-29T20:01:50+00:00 app[web.2]: [stack]: [Getter/Setter],
2013-01-29T20:01:50+00:00 app[web.2]: [type]: 'non_object_property_load',
2013-01-29T20:01:50+00:00 app[web.2]: [message]: [Getter/Setter],
2013-01-29T20:01:50+00:00 app[web.2]: [arguments]: [ 'quiet', undefined, [length]: 2 ] }

This happened only when I scaled up to 10 nodes during a test, and only showed up on some of the nodes. Restarting those nodes didn't fix the problem.

Problem went away when I scaled back down to 4 nodes.

Ability to list memcached keys?

Hi Memjs team!

Is there any way to list the current keys stored on a Memcached server using this module?

It would be great to be able to list the current keys, so that a dev could then target and delete/set the particular subset of keys that need refreshing.

Something like.

var memjs = require('memjs')
var client = memjs.Client.create()

client.getKeys(function(err, keys) { 
  console.log(keys);  //would output  an array of keys indicating what is stored on memcache
})

Otherwise I or any other dev using this module will have to hammer Memcachier with all possibilities to ensure that a particular subset of keys have been updated.

It could also be that I just plain missed this functionality while reading through the memjs.js file, or that this can be done by manually logging in to the memcached server and doing this via the terminal. Any guidance/additional documentation is greatly appreciated!

Thanks,
Daniel

.get() Doesn't Return Key

Hi all,

Firstly, I really like this library. Very very nice to have something which is super simple and handles everything.

I just started using this in a production application, and noticed an issue when performing .get() requests -- the key value isn't returned properly as I'd expect.

Here's what I'm doing:

var memjs = require('memjs');

var cache = memjs.Client.create();

setInterval(function() {
  cache.get('some-key', function(err, value, key) {
    if (err) throw err;
    console.log('key:', key.toString());
    console.log('value:', value.toString());
  });
}, 60000);

What I get is a proper value (as I'd expect), but no Key value returned (eg: 'some-key'). It feels like this is a bug, as the docs suggest that key should contain the returned key name.

Poor error on connection issue

I forgot to fire up my local memcached server when running my project locally, and memjs gave back the following error:

TypeError: undefined is not a function
at Server.error (.../node_modules/memjs/lib/memjs/server.js:43:30)

Set does not support writing flags

Flags is being retrieved and is the third parameter of the get callback. Flags is an arbitrary 32-bit unsigned integer (written out in decimal) that the server stores along with the data and sends back when the item is retrieved. Clients may use this as a bit field to store data-specific information; this field is opaque to the server.

Memjs should support setting it as well.

Get / Set JSON Value?

I'm having some issues when attempting to set and get a JSON value, currently I have some code similar to the following:

      memcache.get(username, function(err, value, key) {
        var query, siteCode, user, userCredentials;
        if (err != null) {
          winston.error("BasicAuth: Error occured when attempting to search memcache for the user, error follows: " + (util.inspect(err)));
          return done(err);
        }
        if (value != null) {
          user = value.toJSON();
          if (passwordHash.verify(password, user.hashedPassword)) {
            winston.info("BasicAuth: User " + username + " with siteCode " + siteCode + " successfully logged in");
            return done(null, user);
          } else {
            return done(null, false, {
              message: 'Invalid username/password combination'
            });
          }
        }
        memcache.set(username, { some: 'JSON value', with: 'A Few', arrays: [] }, function(err, success) {
          if (err != null) {
            winston.error("BasicAuth: Failed to store the users details in memcache, error follows: " + (util.inspect(err)));
            return done(null, userDetails);
          }
          winston.info("BasicAuth: Successfully stored user's details in the memcache server");
          winston.info("BasicAuth: User " + username + " with siteCode " + siteCode + " successfully logged in");
          return done(null, {});
        })
      }

But when I call the get and then user = value.toJSON(); I get a zero length array!?

Values with special characters are truncated

Hi guys,

When I get a value containing special characters, the toString() function truncates the value :

var cache = new memjs.Client.create();

// Sets a value with 6 characters, 4 are special
cache.set("test", 'éééoào', function(err, val) {      
  cache.get("test", function(err, val) {      
    // Displays the length of the buffer, 
    // the length of the string decoded from the buffer
    // and the buffer itself
    console.log( val.length, val.toString().length, val );
    console.log( val.toString() );
  });
});

I have the following result :

6 3 <Buffer c3 a9 c3 a9 c3 a9>
ééé

Cheers !

Support for v0.8?

Can you add v0.8 node.js to package.json so it can be used in v0.8 projects?

Thanks

Expiration value could indicate clearer the two different modes (interval vs timestamp)

Hi,
I was attempting to set the TTL value in milliseconds instead of seconds using the SET method. The value i was using for TTL was 1 hour. The SET command would complete without error, but any following GET requests could not find the data. After realizing the method expects TTL in seconds, everything worked as expected.

What is the maximum permitted TTL value? I know this is my own fault for not reading the documentation more closely, but it would be nice to receive an error message if the TTL value is invalid instead of silently failing.

Cheers, Adam.

This socket has been ended by the other party

I am facing these error messages in my production application:

MemJS: Server pub-memcache-12821.us-east-1-4.4.ec2.garantiadata.com:12821 failed after (10) retries with error - This socket has been ended by the other party
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

This is happening every time I start my application with more than ~7 machines connecting to the same memcache server. I am alo using clusters, which is leading me to suspect that the server is not being able to handle opening all connections and memjs's retry logic is somehow flawed.

Connection trouble with 0.10.0

After updating to 0.10.0 we starting seeing connection issues which were hard to diagnose. We've downgraded back to 0.9.0 and it doesn't look like we're seeing them anymore.

What would happen was that simply that a process would start spewing Error: socket timed out waiting on response. ~10 times a minute and be unable to re-establish a connection to the memcache server (we're using AWS Elasticache). New processes would connect with no issue.

I wish I had more details to report, but so far I've been unable to reproduce this outside of a production environment. I'll update this post as I learn more.

Error: write EPIPE on Heroku

I have an application which works fine with local memcached. But on heroku with MemCachier I always get this error:

The file is under 1MB so I don't have any idea...

With node 0.12.7 and iojs 3.0.0

2015-08-14T09:58:23.326274+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.326348+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.326410+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.326450+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.325681+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.326497+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.340426+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.344439+00:00 app[web.1]: memjs error: { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
2015-08-14T09:58:23.345524+00:00 app[web.1]: MemJS: Server mc2.dev.eu.ec2.memcachier.com:11211 failed after (2) retries with error - write EPIPE
2015-08-14T09:58:23.346038+00:00 app[web.1]: memjs error: { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
2015-08-14T09:58:23.352236+00:00 app[web.1]: Debug: internal, implementation, error
2015-08-14T09:58:23.352240+00:00 app[web.1]: SyntaxError: Uncaught error: Unexpected end of input
2015-08-14T09:58:23.352243+00:00 app[web.1]: at Object.parse (native)
2015-08-14T09:58:23.352245+00:00 app[web.1]: at /app/tariffs/index.js:22:20
2015-08-14T09:58:23.352246+00:00 app[web.1]: at /app/node_modules/memjs/lib/memjs/memjs.js:143:19
2015-08-14T09:58:23.352248+00:00 app[web.1]: at Object.errorHandler (/app/node_modules/memjs/lib/memjs/memjs.js:504:21)
2015-08-14T09:58:23.352250+00:00 app[web.1]: at Server.error (/app/node_modules/memjs/lib/memjs/server.js:54:16)
2015-08-14T09:58:23.352252+00:00 app[web.1]: at Socket. (/app/node_modules/memjs/lib/memjs/server.js:119:12)
2015-08-14T09:58:23.352253+00:00 app[web.1]: at Socket.emit (events.js:107:17)
2015-08-14T09:58:23.352255+00:00 app[web.1]: at onwriteError (_stream_writable.js:317:10)
2015-08-14T09:58:23.352257+00:00 app[web.1]: at onwrite (_stream_writable.js:335:5)
2015-08-14T09:58:23.352258+00:00 app[web.1]: at WritableState.onwrite (_stream_writable.js:105:5)

Enable individual expiration time on each SET

I'm caching stuff that has a variable expiration time - eg. caching of HTTP-responses where I want the expiration to correspond pretty well to the cache time that was indicated in the response. Right now MemJS expects the expiration time to be set on initialization - I would prefer if that setting was possible to override on an individual set.

Thanks for an otherwise great lib! Works wonderfully with Heroku

Key hashing can lead to undefined server references

Because utils.hashCode() can sometimes return negative values, and Client.prototype.server() uses a mod to get the server index, certain keys map to an undefined server.

To reproduce:
utils.hashCode("ffffff") // returns -1277454784

Error after ECONNRESET

Hi, I found this in my Heroku logs:

2014-01-09T17:44:19.458950+00:00 app[web.2]: MemJS: Server <......heroku.prod.memcachier.com:11211> failed after (2) retries with error - write ECONNRESET 2014-01-09T17:44:19.459551+00:00 app[web.2]: 2014-01-09T17:44:19.459980+00:00 app[web.2]: /app/node_modules/memjs/lib/memjs/memjs.js:226 2014-01-09T17:44:19.460251+00:00 app[web.2]: callback(err, null, null); 2014-01-09T17:44:19.460251+00:00 app[web.2]: ^ 2014-01-09T17:44:19.465615+00:00 app[web.2]: TypeError: undefined is not a function 2014-01-09T17:44:19.465615+00:00 app[web.2]: at /app/node_modules/memjs/lib/memjs/memjs.js:226:7 2014-01-09T17:44:19.465615+00:00 app[web.2]: at Object.errorHandler [as undefined] (/app/node_modules/memjs/lib/memjs/memjs.js:410:19) 2014-01-09T17:44:19.465615+00:00 app[web.2]: at Server.error (/app/node_modules/memjs/lib/memjs/server.js:54:16) 2014-01-09T17:44:19.465615+00:00 app[web.2]: at Socket.<anonymous> (/app/node_modules/memjs/lib/memjs/server.js:117:12) 2014-01-09T17:44:19.465615+00:00 app[web.2]: at Socket.EventEmitter.emit (events.js:95:17) 2014-01-09T17:44:19.465615+00:00 app[web.2]: at process._tickCallback (node.js:415:13) 2014-01-09T17:44:19.465615+00:00 app[web.2]: at net.js:441:14 2014-01-09T17:44:20.748990+00:00 heroku[web.2]: Process exited with status 8 2014-01-09T17:44:20.762325+00:00 heroku[web.2]: State changed from up to crashed

Looks like memjs calls an undefined function in case of a ECONNRESET of the memcache server.

Thanks, Philip

Performance

I finally got the opportunity to update my dependency from the 'memjs-concurrent' package to the latest 'memjs' version.

Unfortunately, my QA guys quickly discovered an over 50% drop in performance in one of our tests directly related to caching. Reverting back to the 'memjs-concurrent' brought performance of that test back to nominal levels.

The test involves 30 concurrent requests over 4 nodes on Heroku with a Memcachier backed cache. The nature of the test is such that each request will pull the same item from the cache. This item is probably on the order of 10K in size.

I wish I had more data. I don't expect to have time in the near future to do a more comprehensive and isolated test.

A way to delete key

Hi there,

I am wondering if there is a way to expire keys using memjs?

Thanks.

response.header.status == 0x20

Hi, I found this code in server.js line 82:

...
} else if (response.header.status == 0x20) {
...

there is no status 0x20 specified in the protocol, what does it mean?

The errorHandler function have a little bug

Hello Alevy,

The errorHandler function in Client.prototype.perform have a little bug, when caller calls get/set etc,the network will get the issue, such as server shutdown or network connection fail and retry fail.

The errorHandler call logger.log to make log only, does not call the callback function anymore, so memjs caller will 'waiting' it's callback function to be call forever.

That's all, please check it.

Thanks.

Lib assumes first response is for last request (race condition)

Hello, and thank you for memjs!

To reproduce:

  1. Run memcached on remote host across WAN (latency may be required, not sure)
  2. In the node shell, run
var memjs = require('memjs'),client = memjs.Client.create();

client.get('hello',function(err,val,extras) {console.log(err + ', ' + val)});client.set('foo','bar',function(err,success) {console.log(err + ', ' + success);});

Assuming key 'hello' does not exist already

Expect:
'Key not found',null // from get request
null,true // from set request

Actual:

> client.get('hello',function(err,val,extras) {console.log(err + ', ' + val)});client.set('foo','bar',function(err,success) {console.log(err + ', ' + success);});
undefined
> null, null
MemJS SET: Key not found
Error: MemJS SET: Key not found, null

The 'get' response (with opcode 0 and status 1 = key not found) is executing in the callback for the 'set' request.

In other words, the last callback registered will be executed upon receipt of the first outstanding response.

It may be necessary to correlate requests with response callbacks in some kind of data structure:

callbacks[opcode][key] = onecallback;

Then when a response arrives, the correct callback can be invoked.

I encountered this at the office today, and have reproduced it in a second environment at home.

Let me know if you have any questions, and keep up the good work!

Function Signatures are Non-Standard

I was hoping to use Bluebird to promisify certain library functions by found an issue where in some functions the final argument doesn't conform to the node convention of lastArg = callback(err,data)

Get() header data type

Hi,
When returning data from a .get() request I need to identify if the data was .set() using a buffer or a string. I'm assuming I could access this information from the header? but it's not included with the get callback.

Without having to track the data types <-> keys in my application, could this be achieved if the header data was returned in the get() callback?

Thanks, Adam.

Unable to connect

Thanks for providing this module.

Getting a connection timeout when attempting to connect to MemCachier instance. (Debugging shows that it does not reach the SASL authentication part.)

Works fine with local memcached instance.

I'm using NodeJs version 0.8.6.

I haven't had the chance to test this out on other platforms. Would be happy to provide Memcachier env variables if necessary.


status code is ignored

From section 4.1(introduction) of the spec:

If the status code of a response packet is non-nil,
   the body of the packet will contain a textual error message.

From section 4.2.1 (get request example):

 If the item exist on the server the following packet is returned,
   otherwise a packet with status code != 0 will be returned (see
   Introduction (Section 4.1))

When I set a non-nil status code on my C++ server, from a get to a non existing key, I see the client's 'get' callback invoked with null error and null value. The callback should be invoked with error set to the response body and null for the value.

Callback should be the last argument

Having something other than a callback as the last function argument goes against node conventions and it's inconsistent with other methods in the module that have callback as the last argument.

Read/write out-of-order bug?

There seems to be a problem with memjs not receiving responses from a (local) memcached server in the order in which they are sent. This can mean that the response to a GET can be confused with the response to a SET, and vice versa.

The read-write-ordering-bug branch of https://github.com/ithinkihaveacat/memjs/tree/read-write-ordering-bug illustrates this problem.

$ node example.js 
writing  <Buffer 80 00 00 03 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 41 41 41>
writing  <Buffer 80 01 00 03 08 00 00 00 00 00 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 42 42 5a 5a 5a>
response =  { header: 
   { magic: 129,
     opcode: 1,
     keyLength: 0,
     extrasLength: 0,
     dataType: 0,
     status: 0,
     totalBodyLength: 0,
     opaque: 0,
     cas: <Buffer 00 00 00 00 00 00 00 03> },
  key: <Buffer >,
  extras: <Buffer >,
  val: <Buffer > }
response =  { header: 
   { magic: 129,
     opcode: 0,
     keyLength: 0,
     extrasLength: 0,
     dataType: 0,
     status: 1,
     totalBodyLength: 9,
     opaque: 0,
     cas: <Buffer 00 00 00 00 00 00 00 00> },
  key: <Buffer >,
  extras: <Buffer >,
  val: <Buffer 4e 6f 74 20 66 6f 75 6e 64> }
MemJS SET: Key not found

The output shows:

  1. The GET request sent to the memcached server.
  2. The SET request sent to the memcached server.
  3. The response to the SET. (The opcode is 1--see section 3.3 of the spec.)
  4. The response to the GET.
  5. memjs incorrectly assuming that the response to GET ("Key not found") is actually the response to the SET.

I've reproduced this bug on both OS X (node 0.8.18, memcached 1.4.5) and Linux (node 0.8.18, memcached 1.4.7).

I'm a bit surprised no-one else has noticed this! Is everyone else using MemCachier, which doesn't respond out-of-order?

Crash Trace

Hi,

I'm seeing this crash in my logs:

Mar 25 15:25:59 app/web.23: MemJS: Server 67439.5b2bbe.us-east-4.heroku.prod.memcachier.com:11211 failed after (2) retries with error - write EPIPE
Mar 25 15:25:59 app/web.23: Trace
Mar 25 15:25:59 app/web.23: at addListener (events.js:179:15)
Mar 25 15:25:59 app/web.23: at once (events.js:204:8)
Mar 25 15:25:59 app/web.23: at Socket. (/app/node_modules/memjs/lib/memjs/server.js:100:12)
Mar 25 15:25:59 app/web.23: at Socket. (/app/node_modules/newrelic/node_modules/continuation-local-storage/node_modules/async-listener/glue.js:188:31)
Mar 25 15:25:59 app/web.23: at Socket.g (events.js:199:16)
Mar 25 15:25:59 app/web.23: at Socket.emit (events.js:129:20)
Mar 25 15:25:59 app/web.23: at TCPConnectWrap.afterConnect as oncomplete

Any ideas on what the issue could be? I'm using memjs 0.8.5.

delete all keys

How do you delete all memcache keys? The delete function requires you to supply the 'key' argument.

Error reporting - Node.js-style callbacks and custom logger

First of all, thanks for this! I've been missing a SASL-capable memcached node.js client for a while now.

In any case - shouldn't all client callbacks follow the node.js style of (err) errbacks and (err, success) or (err, data) callbacks? IMO, reporting success with callback(response.val) or callback(true) is confusing, as the first argument is for reporting errors. In this line of thought, I also believe errors shouldn't be just logged to console but passed to the callback so that userland code can decide on its recovery strategy, or perhaps so that errors can bubble up so that higher-level operations fail with an informative error.

Finally, I don't think you should be hard-coding console as a logger, e.g. I might want to log with util, or Winston, or not log at all.

What do you think?

Regards,
Hristo

Global variable (memory leak?)

Hi,

On line 70 of utils.js, the variable 'originalValue' is not declared using var, this results in it being defined as a global variable instead of a local variable. You should consider using strict mode to prevent these errors.

Cheers,
Adam.

Timeout doesn't work for SASL auth

Not sure if this is by design but the timeout support doesn't work for the situation of:

  1. Socket connects
  2. Send SASL auth
  3. Wait forever on server to respond to SASL auth

It may make sense for SASL auth to have a longer timeout than normal, but if so, lets just add a second configuration parameter for this rather than having no timeout at all.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.