NAME
EventStore::Tiny - A minimal event sourcing framework.
SYNOPSIS
use EventStore::Tiny;
my $store = EventStore::Tiny->new;
# Register event type
$store->register_event(UserAdded => sub ($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:
{}
- slack
-
See "SLACK MODE" below. Default: 0
- 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
import_events
$store->import_events($filename);
Loads events from a file which was written by "export_events" before. It replaces an existing event stream in $store
. Note: before using the resulting events, the event types need to be registered as the transformations are only referenced.
export_events
$store->export_events($filename);
Serializes the event stream to the file system. It can be imported back via "import_events" later.
EVENT SOURCING WORKFLOW
register_event
$store->register_event(ConnectionRemoved => sub ($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.
events
my $event_stream = $store->events;
Returns the internal EventStore::Tiny::EventStream object that stores all concrete events (EventStore::Tiny::Event instances). Should be manipulated by "store_event" only. Events should never be changed or removed.
trans_store
my $transformation_store = $store->trans_store
Returns the internal EventStore::Tiny::TransformationStore object that stores all transformation subroutines that events refer to. Should be manipulated by "register_event" only. The transformation store should never be changed or removed.
init_state
my $state = $store->init_state;
Returns a cloned copy of the initial state all events are applied on, which was defined by "init_data" as a hashref.
SLACK MODE
By default, EventStore::Tiny is in strict mode. That means, that all "snapshot" data is cloned to prevent the internal state from illegal modification. However, if you really know what you're doing, you can activate "slack" mode to get references to the internal (cached) state. This improves performance a lot, but has also the downside that it can break your data consistence. You really have to make sure, that you modify your data with events only!
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-2021 Mirko Westermeier (@memowe, mirko@westermeier.de)
Released under the MIT License (see LICENSE.txt for details).