All Projects → ZilvinasKucinskas → Frp Eventsourcing

ZilvinasKucinskas / Frp Eventsourcing

Licence: mit
Functional Reactive Programming in Event Sourcing Systems

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to Frp Eventsourcing

assembler
Functional, type-safe, stateless reactive Java API for efficient implementation of the API Composition Pattern for querying/merging data from multiple datasources/services, with a specific focus on solving the N + 1 query problem
Stars: ✭ 102 (-12.82%)
Mutual labels:  event-sourcing, reactive-programming, functional-reactive-programming
Eventstore
The stream database optimised for event sourcing
Stars: ✭ 4,395 (+3656.41%)
Mutual labels:  event-sourcing, eventsourcing
Netcoremicroservicessample
Sample using micro services in .NET Core 3.1 Focusing on clean code
Stars: ✭ 403 (+244.44%)
Mutual labels:  event-sourcing, eventsourcing
Bifrost
This is the stable release of Dolittle till its out of alpha->beta stages
Stars: ✭ 111 (-5.13%)
Mutual labels:  event-sourcing, eventsourcing
Akka Stream Eventsourcing
Event sourcing for Akka Streams
Stars: ✭ 105 (-10.26%)
Mutual labels:  event-sourcing, reactive-programming
Awesome Rxjs
A collection of awesome RxJS resources
Stars: ✭ 314 (+168.38%)
Mutual labels:  reactive-programming, functional-reactive-programming
Eventsourcing
A library for event sourcing in Python.
Stars: ✭ 760 (+549.57%)
Mutual labels:  event-sourcing, eventsourcing
delta
DDD-centric event-sourcing library for the JVM
Stars: ✭ 15 (-87.18%)
Mutual labels:  event-sourcing, eventsourcing
Eventhorizon
CQRS/ES toolkit for Go
Stars: ✭ 961 (+721.37%)
Mutual labels:  event-sourcing, eventsourcing
Go Cqrs All
All-in-one collection for Go CQRS / ES / DDD examples
Stars: ✭ 39 (-66.67%)
Mutual labels:  event-sourcing, eventsourcing
Rocket.jl
Functional reactive programming extensions library for Julia
Stars: ✭ 69 (-41.03%)
Mutual labels:  reactive-programming, functional-reactive-programming
Marten
.NET Transactional Document DB and Event Store on PostgreSQL
Stars: ✭ 1,654 (+1313.68%)
Mutual labels:  event-sourcing, eventsourcing
Swiftrex
Swift + Redux + (Combine|RxSwift|ReactiveSwift) -> SwiftRex
Stars: ✭ 267 (+128.21%)
Mutual labels:  event-sourcing, reactive-programming
Lpdmvvmkit
LPDMvvmKit - Elegant MVVM framework in Objective-C.
Stars: ✭ 400 (+241.88%)
Mutual labels:  reactive-programming, functional-reactive-programming
EsBankAccount
Bank Account kata and Functional Event Sourcing in F#
Stars: ✭ 63 (-46.15%)
Mutual labels:  event-sourcing, eventsourcing
Reactiveui
An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms that is inspired by functional reactive programming. ReactiveUI allows you to abstract mutable state away from your user interfaces, express the idea around a feature in one readable place and improve the testability of your application.
Stars: ✭ 6,709 (+5634.19%)
Mutual labels:  reactive-programming, functional-reactive-programming
Event Store Client
PHP 7.4 Event Store Client Implementation
Stars: ✭ 93 (-20.51%)
Mutual labels:  event-sourcing, eventsourcing
fpEs
Functional Programming for EcmaScript(Javascript)
Stars: ✭ 40 (-65.81%)
Mutual labels:  reactive-programming, functional-reactive-programming
reacted
Actor based reactive java framework for microservices in local and distributed environment
Stars: ✭ 17 (-85.47%)
Mutual labels:  event-sourcing, reactive-programming
Cycle State Machine Demo
Non-trivial, real use case demo of a hierarchical state machine library with cyclejs
Stars: ✭ 25 (-78.63%)
Mutual labels:  reactive-programming, functional-reactive-programming

Build Status Gem Version Code Climate

Frp-Eventsourcing

EventSourcing describes current state as series of events that occurred in a system. Events hold all information that is needed to recreate current state. This method allows to achieve high volume of transactions, and enables efficient replication. Whereas reactive programming lets implement reactive systems in declarative style, decomposing logic into smaller, easier to understand components. The goal is to create reactive programming program interface, incorporating both principles. Applying reactive programming in event-sourcing systems enables modelling not only instantaneous events, but also have their history. Furthermore, it enables focus on the solvable problem, regardless of low level realization details. Reactive operators enable read model creation without exposing realization details of operations with data storage.

Sources to learn more about

(Functional) Reactive programming

EventSourcing

Installation

Add this line to your application's Gemfile:

gem 'frp-eventsourcing'

And then execute:

$ bundle

Or install it yourself as:

$ gem install frp-eventsourcing

Usage

Generate EventStore event model

Use provided task to generate a table to store events in your database.

rails generate frp_eventsourcing:migration
rake db:migrate

Event definitions

# Define events
AccountCreated = Class.new(FrpEventsourcing::Event)
MoneyDeposited = Class.new(FrpEventsourcing::Event)
MoneyWithdrawn = Class.new(FrpEventsourcing::Event)

Alternative definition:

class AccountCreated < FrpEventsourcing::Event; end
class MoneyDeposited < FrpEventsourcing::Event; end
class MoneyWithdrawn < FrpEventsourcing::Event; end

Create stream

We can define stream that is creating read model once in our app. Keep in mind that no database operations are present here.

account_stream = FrpEventsourcing::Stream.new(AccountCreated, MoneyDeposited, MoneyWithdrawn).
  as_persistent_type(Account, %i(account_id)).
  init(-> (state) { state.balance = 0 }).
  when(MoneyDeposited, -> (state, event) { state.balance += event[:data][:amount] }).
  when(MoneyWithdrawn, -> (state, event) { state.balance -= event[:data][:amount] })

Instead of passing lambda directly, we can also use a variable to save and reuse lambda:

account_initial_state_change_function = -> (state) { state.balance = 0 }

or even use a class that implements call method. We can structure our code with some kind of denormalizer for example:

class Denormalizers::ReadModelType::InitialState::Account
  def call(state)
    state.balance = 0
  end
end

Publish events

We can create an account:

stream_name = "account"
event = AccountCreated.new(data: {
          account_id: 'LT121000011101001000'
        })
FrpEventsourcing::EventRepository.new.create(event, stream_name)

Transfer some money (100$ for example) to the account:

stream_name = "account"
event = MoneyDeposited.new(data: {
          account_id: 'LT121000011101001000',
          amount: 100
        })
FrpEventsourcing::EventRepository.new.create(event, stream_name)

Withdraw some money (25$ for example) from the account:

stream_name = "account"
event = MoneyWithdrawn.new(data: {
          account_id: 'LT121000011101001000',
          amount: 25
        })
FrpEventsourcing::EventRepository.new.create(event, stream_name)

Now we can query read model like:

account = Account.find_by(account_id: 'LT121000011101001000')
puts account.balance # prints 75

Available reactive operators

  • merge(another_stream) - merge one stream to another.
  • filter(predicate_function) - if predicate function returns false, event won't get propogated through the chain any more.
  • map(transform_function) - applies transformation function and propogates event through the chain.
  • init(initial_state_change_function) - applies initial state change function for the first event.
  • when(event_type, state_change_function) - if event matches event type, record is being created or loaded, state change function is being applied for the record and transition state saved to database.
  • each(state_change_function) - same as when operator, just does not check event type and applies state change function for each event.

Implementation

Reactive operators were implemented using Observer design pattern, object oriented programming principles and introspection.

Transition state is being solved by applying metaprogramming (introspection, reflection) and using method chaining.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Possible improvements

Easy-medium difficulty:

  • Make demo application with UI. Controller should publish events. Event types and streams should be defined in some kind of initializer file for example.
  • Improve error handling - could be bugs, because it's just prototype version.
  • Refactor event publishing mechanics. We can borrow optimistic locking from RailsEventStore
  • More tests

Challenging:

  • Make mechanics for recreating read models after changes. We should reapply all associated events.
  • Use custom events repository + instructions how to change adapter for FrpEventsourcing::EventRepository

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ZilvinasKucinskas/FRP-EventSourcing.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

The gem is available as open source under the terms of the MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].