NAME

Fugu::StateFile - a small JSON state file

SYNOPSIS

use Fugu::StateFile;

my $store = Fugu::StateFile->new(
    path => '/var/db/myapp/state.json',
    mode => 0600,
)->load;

$store->set(installed => 1);
my $installed = $store->get('installed');

DESCRIPTION

Fugu::StateFile is the file where a daemon and its tools keep the handful of facts that must survive a restart: a counter, a flag, a timestamp. It is that file and nothing more. It holds no PID logic and starts no subprocess: Fugu::Pidfile owns the first, and the caller owns the second.

load() tolerates a missing file and a corrupt one. A state file that a crash truncated must not stop the program that would rewrite it. save() is atomic, through Fugu::File, so the file is never the corrupt one that the next load() has to tolerate.

new

new(%args) creates a store. The method does not touch the file. Call load().

These are the arguments:

path

The state file. This argument is necessary.

mode

The file mode. The default is 0600, because a state file often holds a secret and a wider mode is a decision, not a default.

load

load() reads the state. An absent file gives empty state with no error. A corrupt file gives empty state and records the reason in error(), so the caller can report it and carry on. The method returns the object either way.

save

save() writes the state, with the mode applied before the content.

get

get($key) returns one value, or undef.

set

set($key, $value) stores one value and saves. A caller that changes several keys uses data() and save() instead of one call for each.

delete

delete($key) removes one value and saves.

data

data() returns the state hash reference itself. A caller that changes several keys at once changes it and then calls save().

path

path() returns the state file.

error

error() returns the most recent failure.

RETURN VALUES

load() returns the object. save(), set() and delete() return the object on success and undef on failure, with the reason in error().

get() returns a value or undef. data() returns a hash reference.

EXAMPLES

This example changes two keys with one write:

$store->data->{running}    = 1;
$store->data->{started_at} = time;
$store->save or warn $store->error . "\n";

ERRORS

new() dies when path is absent or empty. That is a programming error.

No other method dies. A failed read and a failed write both report through the return value and error().

SEE ALSO

Fugu::Config, Fugu::File, Fugu::Pidfile

AUTHORS

Dick Olsson <hi@senzilla.io>

CAVEATS

The store is not shared state. Two processes that hold the same file both keep their own copy in memory, and the last save() wins. A process that must not lose a concurrent change reloads before it writes, or takes a lock of its own.

Every value goes through JSON. A code reference, a file handle, or a blessed object does not encode, and the save() that meets one fails.