Home

Awesome

Run tests <a href='https://coveralls.io/github/tarantool/expirationd?branch=master'> <img src='https://coveralls.io/repos/github/tarantool/expirationd/badge.svg?branch=master' alt='Coverage Status' /> </a>

expirationd - data expiration with custom quirks.

This package can turn Tarantool into a persistent memcache replacement, but is powerful enough so that your own expiration strategy can be defined.

You define two functions: one takes a tuple as an input and returns true in case it's expired and false otherwise. The other takes the tuple and performs the expiry itself: either deletes it (memcache), or does something smarter, like put a smaller representation of the data being deleted into some other space.

There are a number of similar modules:

Table below may help you to choose a proper module for your requirements:

ModuleReaction timeUses indicesArbitrary conditionExpiration trigger
indexpirationHigh (ms)YesNosynchronous (fiber with condition)
expirationdMedium (sec)YesYessynchronous (fiber with condition)
moonwalkerNANoYesasynchronous (using crontab etc)

Prerequisites

Installation

You can:

Documentation

See API documentation in https://tarantool.github.io/expirationd/

Note about using expirationd with replication: by default expirationd processes tasks for all types of spaces only on the writable instance. It does not process tasks on read-only instance for non-local persistent spaces. It means that expirationd will not start task processing on a replica for regular spaces. One can force running task on replica with option force in start() module function. The option force let a user control where to start task processing and where don't.

Examples

Simple version:

box.cfg{}
space = box.space.old
job_name = "clean_all"
expirationd = require("expirationd")

function is_expired(args, tuple)
  return true
end

function delete_tuple(space, args, tuple)
  box.space[space]:delete{tuple[1]}
end

expirationd.start(job_name, space.id, is_expired, {
    process_expired_tuple = delete_tuple,
    args = nil,
    tuples_per_iteration = 50,
    full_scan_time = 3600
})

Сustomized version:

expirationd.start(job_name, space.id, is_expired, {
    -- name or id of the index in the specified space to iterate over
    index = "exp",
    -- one transaction per batch
    -- default is false
    atomic_iteration = true,
    -- delete data that was added a year ago
    -- default is nil
    start_key = function( task )
        return clock.time() - (365*24*60*60)
    end,
    -- delete it from the oldest to the newest
    -- default is ALL
    iterator_type = "GE",
    -- stop full_scan if delete a lot
    -- returns true by default
    process_while = function( task )
        if task.args.max_expired_tuples >= task.expired_tuples_count then
            task.expired_tuples_count = 0
            return false
        end
        return true
    end,
    -- this function must return an iterator over the tuples
    iterate_with = function( task )
        return task.index:pairs({ task.start_key() }, { iterator = task.iterator_type })
            :take_while( function( tuple )
                return task:process_while()
            end )
    end,
    args = {
        max_expired_tuples = 1000
    }
})

Testing

$ make deps-full
$ make test

Regression tests running in continuous integration that uses luatest are executed in shuffle mode. It means that every time order of tests is pseudorandom with predefined seed. If tests in CI are failed it is better to reproduce these failures with the same seed:

$ make SEED=1334 test
luatest -v --coverage --shuffle all:1334
...

Cartridge role

cartridge.roles.expirationd is a Tarantool Cartridge role for the expirationd package with features:

Tarantool 3.0 role

roles.expirationd is a Tarantool 3.0 role for the expirationd package with the following features: