1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-09 00:22:08 +03:00
Files
node-redis/docs/blocking-commands.md
Leibale c188a5c781 docs
Co-authored-by: Guy Royse <guy@guyroyse.com>
2023-06-14 15:01:52 -04:00

2.5 KiB

Blocking Commands

Any command can be run on a new connection by specifying the isolated option. The newly created connection is closed when the command's Promise is fulfilled.

This pattern works especially well for blocking commands—such as BLPOP and BLMOVE:

import { commandOptions } from 'redis';

const blPopPromise = client.isolated().blPop(
  'key',
  0
);

await client.lPush('key', ['1', '2']);

await blPopPromise; // '2'

To learn more about isolated execution, check out the guide.

Isolated Execution

Sometimes you want to run your commands on an exclusive connection. There are a few reasons to do this:

  • You're using transactions and need to WATCH a key or keys for changes.
  • You want to run a blocking command that will take over the connection, such as BLPOP or BLMOVE.
  • You're using the MONITOR command which also takes over a connection.

Below are several examples of how to use isolated execution.

NOTE: Behind the scenes we're using generic-pool to provide a pool of connections that can be isolated. Go there to learn more.

The Simple Scenario

This just isolates execution on a single connection. Do what you want with that connection:

await client.executeIsolated(async isolatedClient => {
    await isolatedClient.set('key', 'value');
    await isolatedClient.get('key');
});

Transactions

Things get a little more complex with transactions. Here we are .watch()ing some keys. If the keys change during the transaction, a WatchError is thrown when .exec() is called:

try {
    await client.executeIsolated(async isolatedClient => {
        await isolatedClient.watch('key');

        const multi = isolatedClient.multi()
            .ping()
            .get('key');

        if (Math.random() > 0.5) {
            await isolatedClient.watch('another-key');
            multi.set('another-key', await isolatedClient.get('another-key') / 2);
        }

        return multi.exec();
    });
} catch (err) {
    if (err instanceof WatchError) {
        // the transaction aborted
    }
}

Blocking Commands

For blocking commands, you can execute a tidy little one-liner:

await client.executeIsolated(isolatedClient => isolatedClient.blPop('key'));

Or, you can just run the command directly, and provide the isolated option:

await client.blPop(
    commandOptions({ isolated: true }),
    'key'
);