eventsource

package module
v0.0.0-...-5b8d9f6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2019 License: MIT Imports: 2 Imported by: 0

README

Event Sourcing

This package implements an Event Sourcing technique where resources are aggregates produced from append only event logs.


Attribution

This package has it's origins in github.com/savaki/eventsource which is licensed under Apache 2.0 which showed a brief spark in 2017. I thank Matt Ho for sharing his work which serves as the foundation to this package.

Documentation

Index

Constants

View Source
const (
	// ErrNotFound should be returned by store implementations when a
	// aggregate could not be found.
	ErrNotFound = Error("not found")

	// ErrNoEventsProduced is returned when changes are applied to produce a
	// new aggregate but the operation results in no new events being
	// produced. Such a condition may not be unexpected depending on the
	// context.
	ErrNoEventsProduced = Error("no events produced")
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Aggregate

type Aggregate interface {
	// On will be called for each event in the resource's history.
	// Implementations should produce an error if the event could not be
	// applied.
	On(event Event) error
}

Aggregate represents the current state of the domain resource and can be thought of as a left fold over events.

type Command

type Command interface {
	// AggregateID represents the id of the aggregate to apply to.
	AggregateID() string
	EventType() string
}

Command encapsulates the data to mutate an aggregate.

Naming Conventions

A Command has been issued by may never result in an event which happens.

Consider the following workflow:

  • A user asks to change a name and issues the `ChangeName` command.
  • The system validates and accepts the command producing a `ChangedName` event.

type CommandHandler

type CommandHandler interface {
	// Apply applies a command to an aggregate to generate a new set of events
	Apply(ctx context.Context, command Command) ([]Event, error)
}

CommandHandler consumes a command and emits Events

type CommandModel

type CommandModel struct {
	ID   string
	Type string
}

CommandModel provides an embeddable struct that implements Command.

func (CommandModel) AggregateID

func (m CommandModel) AggregateID() string

AggregateID implements the Command interface; returns the aggregate id

func (CommandModel) EventType

func (m CommandModel) EventType() string

type Error

type Error string

Type Error implements the Error interface and is allows for errors to be exported as constants.

func (Error) Error

func (e Error) Error() string

Error implements the standard go Error interface.

type Event

type Event interface {
	// AggregateID implementations should return the id of the resource
	// an aggregation of events produces.
	AggregateID() string

	// EventVersion implementations should returns the resources current
	// version number.
	EventVersion() int64

	// EventAt implementations should return the timestamp marked when the
	// event occurred
	EventAt() time.Time

	// EventType returns the name of the event which is expected to be
	// past tense (e.g., "changedName")
	EventType() string
}

Event implementations structure individual state changes to a resource.

Naming Conventions

An Event has happened and is immutable. When naming Events use past tense. Consider the following workflow:

  • A user asks to change a name and issues the `ChangeName` command.
  • The system validates and accepts the command producing a `ChangedName` event.

type History

type History []Record

History is a chain of events for a specific resource. Left-folding over these events will produce a resource aggregate.

func (History) Len

func (h History) Len() int

Len implements the sort.Interface.

func (History) Less

func (h History) Less(a, b int) bool

Less implements sort.Interface.

func (History) Swap

func (h History) Swap(a, b int)

Swap implements the sort.Interface.

type Record

type Record struct {
	Data    []byte
	Version int64
}

Record is a serialized event suitable for storage.

type Serializer

type Serializer interface {
	// Bind registers one or more events to the Serializer
	Bind(events ...Event) error

	// MarshalEvent implementations should serialize an Event into a Record
	// suitable for storage.
	MarshalEvent(event Event) (Record, error)

	// UnmarshalEvent implementations should deserialize a Record into an Event.
	UnmarshalEvent(record Record) (Event, error)
}

Serializer implementations should serialize Events so they can be stored. Once serialized, an Event is called a Record.

type Store

type Store interface {
	// Save implementations should persist Record(s) to the store.
	Save(ctx context.Context, aggregateID string, records ...Record) error

	// Load implementations should read the records stored up to the
	// specified version or all events if toVersion is `0`. Specify the
	// fromVersion `0` to begin reading the tail of the event chain.
	Load(ctx context.Context, aggregateID string, fromVersion, toVersion int64) (History, error)
}

Store provides an abstraction for the Repository to save data

Directories

Path Synopsis
idgen
Package idgen produces IDs suitable for our example.
Package idgen produces IDs suitable for our example.
person
Package
Package
session
Package session stubs a package for our event source example which would provide session management and accessors to values stored in context.
Package session stubs a package for our event source example which would provide session management and accessors to values stored in context.
serializer
gob
store
memory
Package memory implements a in-memory story which supports the Event Source package which is intended to be used for test cases.
Package memory implements a in-memory story which supports the Event Source package which is intended to be used for test cases.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL