The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

EventStore::Tiny - A minimal event sourcing framework.

CPAN version Travis CI tests Codecov test coverage Coveralls test coverage CPANTS kwalitee score
CPAN testers reports CPAN testers matrix GitHub repository GitHub issue tracker

SYNOPSIS

    use EventStore::Tiny;

    my $store = EventStore::Tiny->new;

    # Register event type
    $store->register_event(UserAdded => sub {
        my ($state, $data) = @_;

        # Use $data to inject the new user into the given $state
        $state->{users}{$data->{id}} = {
            name => $data->{name},
        };
    });

    # ...

    # Store an event instance represented by type and data
    $store->store_event(UserAdded => {id => 17, name => 'Bob'});

    # ...

    # Work with the current state snapshot generated by event application
    say 'His name is ' . $store->snapshot->state->{users}{17}{name}; # Bob

DESCRIPTION

In Event Sourcing, the state of a system is calculated as the application of a stream of events representing each change of the system. This framework is a minimal approach to use these mechanics in simple perl systems and offers these features:

  • Flexible snapshots (high-resolution timestamps) and event substreams.

  • Customizable event logging.

  • Simple storage solution for events in the file system.

  • Transparent snapshot caching mechanism to improve performance.

The internal state of the system needs to be represented by a simple (nested) hash and all events need to operate on this hash only (by side-effect).

REFERENCE

EventStore::Tiny implements the following attributes and methods, grouped by topic.

CONSTRUCTION AND PERSISTENCE

new

    my $store = EventStore::Tiny->new(init_data => {answer = 42});

Standard constructor. Understands all attributes as arguments. For most use cases, these are the sensible arguments:

init_data

A hashref representing the initial state. Default: {}

cache_distance

The number of events after a new snapshot is cached for accellerated access. 0 means the cache is updated after each event. undef means the system does not use any caching. Default: 0

logger

A subref (callback) which will be called each time an event is applied to the state. The callback gets this event as its only argument. Default: "log_cb" in EventStore::Tiny::Logger

new_from_file

    my $store = EventStore::Tiny->new_from_file($filename);

Deserializes an existing store object which was "store_to_file"d before.

store_to_file

    $store->store_to_file($filename);

Serializes the store object to the file system. It can be deserialized via "new_from_file" later.

EVENT SOURCING WORKFLOW

register_event

    $store->register_event(ConnectionRemoved => sub {
        my ($state, $data) = @_;
        # Change $state depending on $data (by side-effect)
    });

Stores an event type in the system by name and action on the $state. Events of this type can be added later to the event store by setting concrete $data with "store_event".

store_event

    $store->store_event(ConnectionRemoved => {id => 42});

Stores a concrete instance of an event type in the event store. The instance is defined by its event type name and a hash of data used by the subref the event uses to manipulate the state.

snapshot

    my $state1    = $store->snapshot->state;

    my $snapshot  = $store->snapshot(1234217421);
    my $state2    = $snapshot->state;
    my $timestamp = $snapshot->timestamp; # 1234217421

Returns a EventStore::Tiny::Snapshot object which basically consists of the corresponding state of the system (represented by a hashref) and the timestamp of the last used event. Snapshots are selected by the given argument timestamp, which returns the current snapshot at the given time. If no timestamp is given, the snapshot represents the last state of the system.

INTROSPECTION

event_names

    my $types = $store->event_names;

Returns an arrayref containing all event type names of registered events, sorted by name. These names are the values of "registry".

registry

    my $user_added = $store->registry->{UserAdded};

Returns a hashref with event type names as keys and event types as values, which are EventStore::Tiny::Event instances. Should be manipulated by "register_event" only.

events

    my $event_stream = $store->events;

Returns the internal EventStore::Tiny::EventStream object that stores all concrete events (EventStore::Tiny::DataEvent instances). Should be manipulated by "store_event" only. Events should never be changed or removed.

init_state

    my $state = $store->init_state;

Returns a cloned copy of the ininitial state all events are applied on, which was defined by "init_data" as a hashref.

OTHER

is_correct_snapshot

    if ($store->is_correct_snapshot($snapshot)) {
        # ...
    }

Checks if a given EventStore::Tiny::Snapshot instance is a valid snapshot of our "events" event store. Mostly used for testing.

REPOSITORY AND ISSUE TRACKER

EventStore::Tiny's source repository is hosted on GitHub together with an issue tracker.

COPYRIGHT AND LICENSE

Copyright (c) 2018 Mirko Westermeier (@memowe, mirko@westermeier.de)

Released under the MIT License (see LICENSE.txt for details).

CONTRIBUTORS