Webtask

Documentation

Storage

Persist JSON data with built-in storage

Persistence

Sometimes your code needs just a little bit of persistent storage, and using a full database feels like too much. Webtask code can durably store a single JSON document up to 500KB in size using built-in storage. With simple get/set APIs and basic conflict detection, this is frequently all you need.

Storage APIs are only available from within named webtasks. They are not available from code submitted for execution as part of the HTTP POST request body.

Reading data

Use the ctx.storage.get API to retrieve a previously stored document:

module.exports = function(ctx, cb) {
    ctx.storage.get(function (error, data) {
        if (error) return cb(error);
        // ...
    });
}

In the absence of error, the data will contain your previously stored document, or null if no document was stored.

Writing data

Use the ctx.storage.set API to save a document:

module.exports = function(ctx, cb) {
    ctx.storage.get(function (error, data) {
        if (error) return cb(error);
        data = data || { counter: 1 };
        ctx.storage.set(data, function (error) {
            if (error) return cb(error);
            // ...
        });
    });
}

In the absence of error, the data has been successfuly persisted.

Resolving conflicts

When many instances of your webtasks attempt to persist the document simultaneously, conflicts may arise. A conflict occurs when the code calls the set operation, and the value of the document in the database is different from the value that was read last by that instance of a webtask. Webtask runtime automatically detects conflicts and allows you to resolve them using an application-specific logic before re-attempting the set call:

module.exports = function(ctx, cb) {
    ctx.storage.get(function (error, data) {
        if (error) return cb(error);
        data = data || { counter: 1 };
        var attempts = 3;
        ctx.storage.set(data, function set_cb(error) {
            if (error) {
                if (error.code === 409 && attempts--) {
                    // resolve conflict and re-attempt set
                    data.counter = Math.max(data.counter, error.conflict.counter) + 1;
                    return ctx.storage.set(data, set_cb);
                }
                return cb(error);
            }
            // ...
        });
    });
}

The absence of error in the callback of set indicates there were no conflicts and the operation persisted the data successfully.

Forcefully writing data

Sometimes you want to disregard the possibility of a conflict and forcefully override whatever data may already be persisted. This can be done with the force option:

module.exports = function(ctx, cb) {
    ctx.storage.set({ counter: 1 }, { force: 1 }, function (error) {
        if (error) return cb(error);
        //...
    });
}

In the absence of error, the data has been successfuly persisted regardless of the existence of a previous version of the data or its value.

Data lifetime

The lifetime of the persisted data is the same as the lifetime of your named webtask. When you delete the webtask, the data is also deleted.