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

@metaparticle/storage

v0.1.0

Published

Scoped storage library

Downloads

5

Readme

Metaparticle/storage

Easy implicit, concurrent persistence for Node.js

Metaparticle/storage makes distributed storage easy.

Implicit, automatic persistence

With Metaparticle/storage you can interact with local variables in a defined scope. Any changes that you make are automatically persisted, even if your server crashes or restarts.

Cloud native, built for distributed systems.

Metaparticle/storage is defined for distributed systems running on multiple machines. In particular Metaparticle/storage ensures read/update/write consistency. If Metaparticle/storage detects a conflict due to multiple concurrent writers it automatically rolls back modifications and re-applies the complete function.

How does it work?

Metaparticle/storage works by defining a collection of scopes. Each scope is a named value which can be obtained by a call to metaparticle.scoped(scopeName, handlerFunction). scopeName provides a unique name for this scoped data. The data itself is passed on to the handlerFunction. Any modifications to the scope are automatically detected and persisted.

Example

Here is a simple web-server which increments a counter and returns the number of requests. Despite looking like a local variable, the counter is kept globably, and persists despite server restarts, scaling or failures. Furthermore, the read/update/write of the counter is automatically atomic, even under concurrent load the system maintains the correct count of requests.

...
var mp = require('@metaparticle/storage');
mp.setStorage('file');

var server = http.createServer((request, response) => {
    // Define a scope for storage, in this case it is a shared 'global' scope.
    mp.scoped('global', (scope) => {
        if (!scope.count) {
            scope.count = 0;
        }
        scope.count++;
        return scope.count;
    }).then((count) => {
        response.end("There have been " + count + (count == 1 ? ' request.' :  ' requests.'));
    });
});

Selecting different storage backends

Metaparticle/storage supports several different storage backends. To select a particular storage implementation, you need to select it with the setStorage(driver, config) function.

Currently Metaparticle supports the following drivers:

  • file: Filesystem-local, useful for testing, not much else.
  • redis: The Redis key/value store
  • mysql: Everone's favorite relational database.

Defining multiple scopes

The total throughput of an application is related to the total number of concurrent requersts for a particular scope. Often it makes sense to partition scopes based on user name, location or other variables. Here is a simple script that partitions the scope by user-name:

var urlObj = url.parse(request.url, true);
    var scopeName = urlObj.query.user;
    if (!scopeName) {
        scopeName = 'anonymous'
    }
    mp.scoped(scopeName, (scope) => {
        if (!scope.count) {
            scope.count = 0;
        }
        scope.count++;
        return scope.count;
    }).then((count) => {
        response.end("There have been " + count + (count == 1 ? ' request.' :  ' requests.'));
    });

Caveats

There's no free lunch. To ensure atmocity, Metaparticle/storage may run your code more than once. Though the data input to the function is reset each time, any other side-effects can not be rolled back.

This means that you must not have side-effects in your code.

Examples of side-effects include:

  • Returning data over an HTTP channel
  • Writing to a file
  • Writing to a non-scoped variable

Metaparticle/storage does not currently detect these side-effects. This means that it is up to you to police your usage and ensure that the code within a scope is side-effect free.

Deep Dive

There is a much deeper dive here, it contains a deeper description of the problems Metaparticle/storage is trying to solve and examples of it in operation.

Bugs

There are probably some