npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redis-scanner

v0.1.1

Published

A simple way to use Redis SCANs from Node.js

Downloads

68

Readme

Redis Scanner Build Status Code Climate Test Coverage

Redis-scanner provides a way to use Redis SCAN in Node.js either synchronously or asynchronously. In terms of compatibility, redis-scanner is built on TravisCI after every commit using Node 0.10.x and 0.12.x. In addition to this, the latest version of io.js is also covered in these builds. Build results are submitted to Code Climate for analysis.

The current version is below v1.0.0 so the potential does exist for breaking changes, however I don't plan on doing this. This module begins as an experiment into the best way to use SCAN. Naturally opinions of this may change over time.

Setup

redis-scanner is available on npm, so simply install it:

$ npm install redis-scanner

Integration

You can bind the methods to your own RedisClient instance, or you can simply create an instance of the Scanner for use.

Binding

Below is an example of binding the methods to your own RedisClient instance. This surfaces the SCAN methods on the client by default.

var redis = require('redis');
var redis_scanner = require('redis-scanner');

var client = redis.createClient();

redis_scanner.bindScanners(client);

Once this is done, you can call any of the scanning methods. These methods can be called using either lower or upper case.

client.scan();
client.hscan();
client.sscan();
client.zscan();

Scanner

Creating an instance of Scanner for use is pretty simple:

var redis = require('redis');
var redis_scanner = require('redis-scanner');

var client = redis.createClient();

var scanner = new redis_scanner.Scanner(client, 'SCAN', key, options);

In the above case, key is equal to the key of the object you're scanning. For SCAN, this is simply null.

The options object looks like the following. Instead of providing args you can optionally provide pattern and count to generate arguments internally. Do not use both.

var options1 = {
    args: ['MATCH','key:*','COUNT','5'],
    onData: function(result[, done]){
    
    },
    onEnd: function(err){
    
    }
};

var options2 = {
    count: '5',
    pattern: 'key:*',
    onData: function(result[, done]){
    
    },
    onEnd: function(err){
    
    }
};

Scanners are reusable. Once you set one up, it will clean up after itself so it can be used again the moment onEnd has been called (i.e. don't run the same Scanner in two places at the same time). To execute, simply call start() on a Scanner instance.

API

Standard API

There are two ways of using redis-scanner, which basically just boils down to personal preference (the backend is the same). The first is designed to be typical of the existing client methods, so it blends into the existing APIs transparently. This takes the form of ([key], [args], onData, onEnd).

// async
client.scan([], function(result, done){
    done();
}, function(err){

});

// sync
client.scan([], function(result){

}, function(err){

});

Depending on the scanning method used, the result argument can be either a single string or an object containing key and value.

// SCAN and SSCAN
'value'

// HSCAN and ZSCAN
{ 'key': 'field', 'value': 'value' }

Please note than SCAN does not take a key argument. However for the other methods HSCAN, SSCAN and ZSCAN, a key must be provided. If none is provided, an error will be thrown.

client.hscan('my_hash', function(entry){

}, function(err){

});

Object API

The alternative is to simply pass all parameters within an object to the scanner. This is similar to how you would use the Scanner constructor directly as shown above.

Please note that key is still a separate parameter when using this API. Arguments passed to onData operate the same way as the Standard API.

client.hscan('my_hash', {
    count: '5',
    pattern: 'key:*',
    onData: function(result[, done]){
    
    },
    onEnd: function(err){
    
    }
});

Notes

Early Exits

Clearly you may sometimes have a need to exit before the iterator is complete (which is incidentally part of the reason why I felt the need to create this library). In this case, the remaining results are simply discarded and execution is halted. The context bound to the function provided as onData contains an end method which will end the processing and exit. Your onEnd will still be called, naturally.

var count = 0;

// only process first 5 hits
client.scan([], function(entry){
    if(++count === 5){
        this.end();
    }
}, function(err){
    console.log(count); // 5
});

Errors

Any errors returned from the Redis client will be passed straight to the onEnd function and the process will be stopped. This is to avoid the case where multiple requests are timing out against the server and causing the process to hang unnecessarily.

Passing an error to the done callback in onData will also halt progress, and forward your err to the onEnd function.

client.scan([], function(entry, done){
    done(new Error('Failed!');
}, function(err){
    console.log(err.message); // 'Failed!'
});

Tests

Naturally, to run the tests you need Redis running. Tests operate on the default database and will wipe existing data, so be careful. Tests are controlled by Grunt.

$ npm test
# or
$ grunt test

You can also generate coverage reports in HTML format using:

$ grunt coverage

and lcov format using:

$ npm run lcov

Issues

If you find any issues inside this module, feel free to open an issue here.