Inanc Gumus
Inanc Gumus

Reputation: 27889

Redis multi with bluebird promises

Do you know a way for using redis client's multiple transactions command with bluebird promises?

Because, the following code never finishes.

  var $redis = require('redis'),
      $p = require('bluebird'),
      $r = $p.promisifyAll($redis.multi());

  $r.setAsync('key', 'test')
    .then(function(reply, data) {
      // ...
    });

  $r.exec(function() {
    $r.quit();
    process.exit();
  });

Upvotes: 2

Views: 4702

Answers (2)

Inanc Gumus
Inanc Gumus

Reputation: 27889

Only thing that is needed for the command not to hang is getting multi with a promisified connection before.

var $redis = require('redis'),
    $p = require('bluebird'),
    $r;

// this is important for bluebird async operations!
$r = $p.promisifyAll($redis.createClient.apply(this, arguments));

// multi also need to be promisifed with the promisified conn above
$r = $p.promisifyAll($r.multi());

$r.setAsync('key', '0').then(function(data) { });
$r.incrAsync('key');

// all of the above commands pipelined above will be executed with this command
$r.execAsync().then(function() {
  $r.quit();

  // this will make the console app (or whatever app) quit
  process.exit();
});

Upvotes: 2

Bergi
Bergi

Reputation: 664375

Is there a way to run exec after these block finishes?

Hm, just chain it:

$r.pfaddAsync('key', item)
  .then(function(result) {
    // marked
    if (result === 0) {
      $r.incrAsync('dup');
    } else {
      $r.incrAsync('unq');
    }
    $r.exec();
  });

or maybe even

$r.pfaddAsync('key', item)
  .then(function(result) {
    // marked
    if (result === 0) {
      $r.incrAsync('dup');
    } else {
      $r.incrAsync('unq');
    }
  })
  .then($r.exec);

Or, if you want to execute it after the incrAsyncs have finished, then it would be

$r.pfaddAsync('key', item)
  .then(function(result) {
    return $r.incrAsync(result === 0 ? 'dup' : 'unq');
//  ^^^^^^
  })
  .then($r.exec);

The .then($r.exec) might not work when exec is required to be called as a method, use .then($r.exec.bind($r)) instead

Upvotes: 1

Related Questions