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

connect-smart-redis

v1.1.0

Published

Like connect-redis, but smarter.

Downloads

6

Readme

Connect Smart Redis

Build Status Coverage Status

connect-smart-redis is inspired by connect-redis. It's fast, light, and (you guessed it) smart!

Usage

Install with:

npm install --save connect-smart-redis

Example:

// Import Express, make the app and the redis client
var express = require('express');
var client = require('redis').createClient();
var app = express();

// Express session finagling
var session = require('express-session');
var SmartRedis = require('connect-smart-redis')(session);

// Actually use the session middleware
var thirtyDays = 30 * 24 * 60 * 60;
app.use(session({
    store: new SmartRedis({ client: client, ttl: thirtyDays }),
    secret: 'hello world!',
    resave: false,
    saveUninitialized: false
}));

// Voila!
app.get('/', function (req, res) {
    req.session.visits = (req.session.visits || 0) + 1;
    res.send('You visited this site ' + req.session.visits + ' times!');
});

app.listen(3000);

Why?

Connect-redis is great, but it was missing several features necessary for some production environments (like ours!). Several improvements were necessary, including:

  • Update as Needed. The original middleware updated redis at the end of every single request, regardless of whether or not the session was actually updated.
  • Locking. As our traffic increased, race conditions appeared where sessions to one request would get overwritten by a request that was happening in parallel. We use the Redlock algorithim to ensure there's only one update at a time. With that:
  • Smart Updates. Only changed properties are updated. This goes well with locking -- there's less a chance of one request stepping on another's feet.
  • Smart Deletions. As a result of the race conditions, we were having difficulty destroying sessions because it would get re-set right over again! Using locking we delete things as expected.

Options

The following options can be passed in its constructor:

  • ttl Time in seconds sessions should last for
  • client a node-redis (or compatible) client
  • prefix=session: The prefix for redis sessions
  • lockExpiry=5000 Time in milliseconds session locks should last for.
  • retryTime=100 Time we should wait if we did no acquire a session lock.
  • deleteExpiry=5000 - The length of a DESTROYED session record should last. This should be at least as long as your longest API request (but does not need to be longer).

Performance

Non-trival parts of the code have been optimized for performance, and of course the middleware itself is built to be a "lazy" as possible. Based on data from our benchmark (using a fake Redis client) the middleware has an overhead of about 3090 nanoseconds (0.03 ms) per transaction. Comparatively, connect-redis ran an overhead of 2610 nanoseconds (0.03 ms) per transaction.

$ node bench\head-to-head.js
connect-redis x 382,937 ops/sec ±0.21% (97 runs sampled)
connect-smart-redis x 323,181 ops/sec ±0.22% (100 runs sampled)

The overhead is pretty minimal on an application level.

But, the locking and updating process does involve four addition Redis queries. If you update the client session in more than 20% of your requests, performance will be degregated using this system. However, you are, it may be a good idea to use smart-redis due to its mitigation of race conditions; it's always a trade off. If you are changing the session in less than 20% of your total requests, you'll see substantially better performance using smart-redis due to the saved request.

Caveats

There is a race condition if two requests simultaneously edit the same attribute of the session. In this event, the request which acquires the lock last will take precedence. There is no way to effectively mitigate this; this is a situation you should bear in mind when building your application.

Additionally, due to the locking, it's possible that if you get very many requests which all edit the session during the same time interval, requests for the particular user may take an unusually long time.

License

This software is MIT licensed, copyright 2015 by Beam LLC.