victorquinn/memcache-plus

Connection not ready issue

Opened this issue · 4 comments

I'm trying to check if the memcached server is up before I run my app (using bufferBeforeError). I have the following code:

  static testConnection () {
    return new Promise((resolve, reject) => {
      const mc = new MemcachePlus({
        hosts: ['localhost:11211'],
        bufferBeforeError: 0
      })

      // I also just tried return mc.set(..) without the outer promise
      mc.set('startup', 'true').then(resolve).catch(reject)
    })
  }

But I keep getting the following thrown/rejected:

Error: Connection is not ready, either not connected yet or disconnected
    at Client.run (/Volumes/sixfive-cs/vault/node_modules/memcache-plus/lib/client.js:467:31)
    at Client.set (/Volumes/sixfive-cs/vault/node_modules/memcache-plus/lib/client.js:307:17)
    at /Volumes/sixfive-cs/vault/lib/TempStorage.js:63:10
    at Function.testConnection (/Volumes/sixfive-cs/vault/lib/TempStorage.js:57:12)
    at Object.<anonymous> (/Volumes/sixfive-cs/vault/bin/vault-server.js:12:13)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3

My memcached server is running; when I switch to an older branch of my code using the memcached module, things work

Note this does work:

    return new Promise((resolve, reject) => {
      const mc = new MemcachePlus({
        hosts: ['localhost:11211'],
        onNetError: function (err) {
          reject(err)
        }
      })

      mc.set('startup', 'true').then(resolve)
    })

Hey @theogravity give it a shot with the latest version of the code when you get a chance, I think I fixed a bug relating to the connection buffering which should resolve this issue.

still no go on ver 0.2.16

doing


function failure (reject, err) {
  log.error(err, 'Memcached storage error')
  reject(getResponseObj(DB_FAILURE))
}

...

  static testConnection () {
    const memcachedConfig = config.memcached

    return new Promise((resolve, reject) => {
      const mc = new MemcachePlus({
        hosts: ['localhost:11211'],
        bufferBeforeError: 0
      })

      mc.set('startup', 'true').then(resolve).catch((err) => {
        failure(reject, err)
      })
    })
  }
Error: Connection is not ready, either not connected yet or disconnected
    at Client.run (/Volumes/sixfive-cs/vault/node_modules/memcache-plus/lib/client.js:516:31)
    at Client.set (/Volumes/sixfive-cs/vault/node_modules/memcache-plus/lib/client.js:307:17)
    at /Volumes/sixfive-cs/vault/lib/TempStorage.js:66:10
    at Function.testConnection (/Volumes/sixfive-cs/vault/lib/TempStorage.js:59:12)
    at Object.<anonymous> (/Volumes/sixfive-cs/vault/bin/vault-server.js:12:13)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3
brenc commented

I ran into this today too. I want bufferBeforeError to be 0 so operations fail immediately when memcached becomes unavailable, but that also means the initial calls fail on application startup because the memcached connection isn't ready when I fire off my initial get() requests.

I dug through the code and noticed that there is a ready() function in the client. What I do is on app startup is set an interval to check if the memcached connection is ready() before proceeding. If after a certain number of seconds the connection isn't ready, I load the app anyway. The goal is to make memcached optional and to fail fast when it's not available.

Perhaps you could add an autoConnect option and when set to false, connect() isn't called on instantiation. Then connect() could be made public and could take a callback and return a Promise like many of the other functions do. I think that would make sense to me (I'm fine with how I'm doing this now though).

If there's a better way to do what I want to do, please let me know!