Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RES 3.0 integration #1561

Draft
wants to merge 59 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
fcf53c3
Revert "Revert "PoC of double serialization prevention""
mostlyobvious Jan 30, 2023
2749fb2
Revert "Revert "Pick correct serializer when testing""
mostlyobvious Jan 30, 2023
d46f9e3
Revert "Revert "Less is more""
mostlyobvious Jan 30, 2023
71b22bb
Revert "Revert "Requirements for different column types""
mostlyobvious Jan 30, 2023
2d21505
Revert "Revert "We don't introduce anything new over Value here""
mostlyobvious Jan 30, 2023
a5319ae
Revert "Revert "Big :brain: time""
mostlyobvious Jan 30, 2023
4339cd1
Revert "Revert "Boom, get proposed type for column from AR and act""
mostlyobvious Jan 30, 2023
68cd8e1
Revert "Revert "Extract to variable""
mostlyobvious Jan 30, 2023
d3b9065
Revert "Revert "More meaningful naming""
mostlyobvious Jan 30, 2023
a5ef54f
Revert "Revert "No idea how to achieve the same in Rails < 6.1""
mostlyobvious Jan 30, 2023
1cedb83
Revert "Revert "Better describing what this test is for""
mostlyobvious Jan 30, 2023
5ec7afa
Revert "Revert "Document how to use json in RES 3.0""
mostlyobvious Jan 30, 2023
d0399e8
Revert "Revert "Raise ArgumentError when trying to publish nil as eve…
mostlyobvious Nov 29, 2022
3c2414f
Revert "Revert "Extract assertion to separate method and call it asap""
mostlyobvious Nov 29, 2022
fa5bb0e
Revert "Revert "Assert nil when linking events""
mostlyobvious Nov 29, 2022
8cffd22
Revert "Remove rename warning"
lukaszreszke Dec 8, 2022
55d674e
Revert "Kill mutants"
lukaszreszke Dec 8, 2022
1e39596
Revert "RailsEventStore 2.6.X should point to RailsEventStoreActiveRe…
lukaszreszke Dec 8, 2022
aefd664
Revert "Remove post install deprecation message for rails_event_store…
lukaszreszke Dec 8, 2022
5acd7df
Ensure only supported any usage by default
swistak35 Jul 26, 2021
81d7a47
No more aggregate root configuration
mpraglowski Jan 5, 2021
9bbac9b
Remove deprecated JSONMapper
mpraglowski Jan 5, 2021
42b477a
NullMapper no longer makes sense without serilizaion in mappers
mostlyobvious Jan 9, 2021
45552b4
EventClassRemapping superseded by upcasting
mostlyobvious Jan 9, 2021
d685cfb
No more aliases on RubyEventStore consts
mostlyobvious Jan 15, 2021
6880ad5
Get rid of dubious meta-apply method handlers
mostlyobvious Jan 9, 2021
165742d
Poor way to ensure with_strategy(->{ Default }) has OnDSL
mostlyobvious Jan 9, 2021
dd7a7b2
Refactor
mostlyobvious Jan 9, 2021
7df8857
Kill mutants
mostlyobvious Jan 9, 2021
9eab186
rails_event_store -> ruby_event_store
mostlyobvious Jan 15, 2021
3864da1
Rename to match passed arguments
mostlyobvious Jan 15, 2021
478b064
Rename to match instrumented methods and their arguments
mostlyobvious Jan 15, 2021
2cddc9e
Projections redesigned
mpraglowski Nov 27, 2022
e2040f3
Recreate EventClassRemapper in contrib/transformations
lukaszreszke Feb 6, 2023
f13b20a
Allow projection from one stream only
lukaszreszke Feb 6, 2023
2b4ce59
Factory method instead of constructor
lukaszreszke Feb 6, 2023
abd2110
Always include OnDSL in DefaultApplyStrategy
lukaszreszke Feb 8, 2023
c08316f
Rename WithDefaultApplyStrategy -> WithDefaultStrategy
lukaszreszke Feb 8, 2023
b35e97f
Custom strategy shouldn't rely on OnDSL
lukaszreszke Feb 8, 2023
1a5261f
Make DeafultApplyStrategy private
lukaszreszke Feb 8, 2023
1afa380
Simplify dispatcher
lukaszreszke Feb 7, 2023
756e021
Rename ImmediateAsyncDispatcher to ImmediateDispatcher
lukaszreszke Feb 7, 2023
935e4d0
Rename AfterCommitAsyncDispatcher to AfterCommitDispatcher
lukaszreszke Feb 7, 2023
c8bc3da
Rename Dispatcher to SyncScheduler
lukaszreszke Feb 8, 2023
d496844
Prefer lazy event store initialization
lukaszreszke Feb 8, 2023
67565f9
Namespace
lukaszreszke Feb 10, 2023
7831958
Remove ANONYMOUS_CLASS guard
lukaszreszke Feb 10, 2023
570e074
Remove anonymous class test from projection_spec
lukaszreszke Feb 10, 2023
8f33187
Using projection with event type defined by event's class
lukaszreszke Feb 13, 2023
1060cac
Add event resolver to projection
lukaszreszke Apr 12, 2023
e7e542b
kill mutant
lukaszreszke Apr 12, 2023
76a8cc2
Kill mutant
lukaszreszke Apr 12, 2023
4a0c022
Change test init for 2.7
lukaszreszke Apr 12, 2023
c0c44a5
Follow instrumentation event renames
mostlyobvious Sep 29, 2023
f5988d8
EventClassRemapper vibes
mostlyobvious Sep 29, 2023
d52040b
AggregateRoot unserscore handlers vibe
mostlyobvious Sep 29, 2023
c70019a
event_store_locator vibes
mostlyobvious Sep 29, 2023
7fb1478
rails_event_store_active_record is no more
mostlyobvious Sep 29, 2023
890dc78
Check whether metadata is transformed to binary
fidel Sep 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions aggregate_root/lib/aggregate_root.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# frozen_string_literal: true

require_relative "aggregate_root/version"
require_relative "aggregate_root/configuration"
require_relative "aggregate_root/transform"
require_relative "aggregate_root/default_apply_strategy"
require_relative "aggregate_root/repository"
require_relative "aggregate_root/instrumented_repository"
Expand All @@ -11,12 +9,9 @@

module AggregateRoot
module OnDSL
ANONYMOUS_CLASS = "#<Class:".freeze

def on(*event_klasses, &block)
event_klasses.each do |event_klass|
name = event_klass.to_s
raise(ArgumentError, "Anonymous class is missing name") if name.start_with? ANONYMOUS_CLASS

handler_name = "on_#{name}"
define_method(handler_name, &block)
Expand Down Expand Up @@ -78,19 +73,24 @@ def marshal_load(vars)
end
end

def self.with_default_apply_strategy
def self.with_default_strategy(strict: true)
Module.new do
def self.included(host_class)
host_class.extend OnDSL
host_class.include AggregateRoot.with_strategy(-> { DefaultApplyStrategy.new })
host_class.extend Constructor
host_class.include AggregateMethods
end

define_method :apply_strategy do
DefaultApplyStrategy.new(strict: strict)
end
end
end

def self.with_strategy(strategy)
Module.new do
def self.included(host_class)
host_class.extend Constructor
host_class.extend Constructor
host_class.include AggregateMethods
end

Expand All @@ -101,6 +101,6 @@ def self.included(host_class)
end

def self.included(host_class)
host_class.include with_default_apply_strategy
host_class.include with_default_strategy
end
end
16 changes: 0 additions & 16 deletions aggregate_root/lib/aggregate_root/configuration.rb

This file was deleted.

32 changes: 14 additions & 18 deletions aggregate_root/lib/aggregate_root/default_apply_strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,35 @@

module AggregateRoot
MissingHandler = Class.new(StandardError)
NullHandler = Proc.new {}

class DefaultApplyStrategy
def initialize(strict: true)
@strict = strict
end

def call(aggregate, event)
name = handler_name(aggregate, event)
if aggregate.respond_to?(name, true)
aggregate.method(name).call(event)
else
raise MissingHandler.new("Missing handler method #{name} on aggregate #{aggregate.class}") if strict
end
on_handler(aggregate, event.event_type)[event]
end

private

def handler_name(aggregate, event)
on_dsl_handler_name(aggregate, event.event_type) || apply_handler_name(event.event_type)
end

def on_dsl_handler_name(aggregate, event_type)
aggregate.class.on_methods[event_type] if aggregate.class.respond_to?(:on_methods)
def on_handler(aggregate, event_type)
on_method_name = aggregate.class.on_methods.fetch(event_type)
aggregate.method(on_method_name)
rescue KeyError
missing_handler(aggregate, event_type)
end

def apply_handler_name(event_type)
"apply_#{Transform.to_snake_case(event_type(event_type))}"
end

def event_type(event_type)
event_type.split(/::|\./).last
def missing_handler(aggregate, event_type)
if strict
raise MissingHandler.new("Missing handler method on aggregate #{aggregate.class} for #{event_type}")
else
NullHandler
end
end

attr_reader :strict, :on_methods
end
private_constant :DefaultApplyStrategy
end
6 changes: 1 addition & 5 deletions aggregate_root/lib/aggregate_root/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module AggregateRoot
class Repository
def initialize(event_store = default_event_store)
def initialize(event_store)
@event_store = event_store
end

Expand All @@ -29,9 +29,5 @@ def with_aggregate(aggregate, stream_name, &block)
private

attr_reader :event_store

def default_event_store
AggregateRoot.configuration.default_event_store
end
end
end
9 changes: 0 additions & 9 deletions aggregate_root/lib/aggregate_root/transform.rb

This file was deleted.

42 changes: 15 additions & 27 deletions aggregate_root/spec/aggregate_root_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,23 @@ def expire

private

def apply_order_created(_event)
@status = :created
on Orders::Events::OrderCreated do |event|
@status = :created
@created_at = event.valid_at
end

def apply_order_expired(_event)
@status = :expired
on Orders::Events::OrderExpired do |event|
@status = :expired
@expired_at = event.valid_at
end
end
end

it "should have ability to apply event on itself" do
order = order_klass.new(uuid)
order_created = Orders::Events::OrderCreated.new

expect(order).to receive(:"apply_order_created").with(order_created).and_call_original
order.apply(order_created)

expect(order.status).to eq :created
expect(order.unpublished_events.to_a).to eq([order_created])
end
Expand All @@ -51,6 +52,12 @@ def apply_order_expired(_event)
expect(order.unpublished_events.to_a).to be_empty
end

it "should raise error for missing apply method based on a default apply strategy" do
order = order_klass.new(uuid)
spanish_inquisition = Orders::Events::SpanishInquisition.new
expect { order.apply(spanish_inquisition) }.to raise_error(AggregateRoot::MissingHandler, "Missing handler method on aggregate #{order_klass} for Orders::Events::SpanishInquisition")
end

it "should receive a method call based on a default apply strategy" do
order = order_klass.new(uuid)
order_created = Orders::Events::OrderCreated.new
Expand All @@ -59,18 +66,9 @@ def apply_order_expired(_event)
expect(order.status).to eq :created
end

it "should raise error for missing apply method based on a default apply strategy" do
order = order_klass.new(uuid)
spanish_inquisition = Orders::Events::SpanishInquisition.new
expect { order.apply(spanish_inquisition) }.to raise_error(
AggregateRoot::MissingHandler,
"Missing handler method apply_spanish_inquisition on aggregate #{order_klass}"
)
end

it "should ignore missing apply method based on a default non-strict apply strategy" do
klass =
Class.new { include AggregateRoot.with_strategy(-> { AggregateRoot::DefaultApplyStrategy.new(strict: false) }) }
Class.new { include AggregateRoot.with_default_strategy(strict: false) }
order = klass.new
spanish_inquisition = Orders::Events::SpanishInquisition.new
expect { order.apply(spanish_inquisition) }.to_not raise_error
Expand Down Expand Up @@ -113,7 +111,7 @@ def custom_expired(_event)
end

it "ruby 2.7 compatibility" do
klass = Class.new { include AggregateRoot.with_default_apply_strategy }
klass = Class.new { include AggregateRoot.with_default_strategy }

# This is just a way to ensure that the AggregateMethods was included on
# the klass directly, not that it was an include to the anonymous module.
Expand Down Expand Up @@ -258,16 +256,6 @@ def custom_expired(_event)
order.apply(Orders::Events::OrderExpired.new)
expect(order.status).to eq(%i[base_expired inherited_expired])
end

it "does not support anonymous events" do
expect do
Class.new do
include AggregateRoot

on(Class.new) { |_ev| }
end
end.to raise_error(ArgumentError, "Anonymous class is missing name")
end
end

describe "#initialize" do
Expand Down
4 changes: 2 additions & 2 deletions aggregate_root/spec/instrumented_repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ def expire

private

def apply_order_created(_event)
on Orders::Events::OrderCreated do |_event|
@status = :created
end

def apply_order_expired(_event)
on Orders::Events::OrderExpired do |_event|
@status = :expired
end
end
Expand Down
39 changes: 2 additions & 37 deletions aggregate_root/spec/repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,51 +29,16 @@ def expire

private

def apply_order_created(_event)
on Orders::Events::OrderCreated do |_event|
@status = :created
end

def apply_order_expired(_event)
on Orders::Events::OrderExpired do |_event|
@status = :expired
end
end
end

def with_default_event_store(store)
previous = AggregateRoot.configuration.default_event_store
AggregateRoot.configure { |config| config.default_event_store = store }
yield
AggregateRoot.configure { |config| config.default_event_store = previous }
end

describe "#initialize" do
it "should use default client if event_store not provided" do
with_default_event_store(event_store) do
repository = AggregateRoot::Repository.new

order = repository.load(order_klass.new(uuid), stream_name)
order_created = Orders::Events::OrderCreated.new
order.apply(order_created)
repository.store(order, stream_name)

expect(event_store.read.stream(stream_name).to_a).to eq [order_created]
end
end

it "should prefer provided event_store client" do
with_default_event_store(double(:event_store)) do
repository = AggregateRoot::Repository.new(event_store)

order = repository.load(order_klass.new(uuid), stream_name)
order_created = Orders::Events::OrderCreated.new
order.apply(order_created)
repository.store(order, stream_name)

expect(event_store.read.stream(stream_name).to_a).to eq [order_created]
end
end
end

describe "#load" do
specify do
event_store.publish(Orders::Events::OrderCreated.new, stream_name: stream_name)
Expand Down
2 changes: 0 additions & 2 deletions aggregate_root/spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
require "ruby_event_store"
require_relative "../../support/helpers/rspec_defaults"

RSpec.configure { |spec| spec.before(:each) { AggregateRoot.configure { |config| config.default_event_store = nil } } }

module Orders
module Events
OrderCreated = Class.new(RubyEventStore::Event)
Expand Down
13 changes: 0 additions & 13 deletions aggregate_root/spec/transform_spec.rb

This file was deleted.

1 change: 0 additions & 1 deletion contrib/dres_rails/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ gem "ruby_event_store", path: "../.."
gem "ruby_event_store-browser", path: "../.."
gem "rails_event_store", path: "../.."
gem "ruby_event_store-active_record", path: "../.."
gem "rails_event_store_active_record", path: "../.."
gem "aggregate_root", path: "../.."

gem "pg"
Expand Down
1 change: 0 additions & 1 deletion contrib/dres_rails/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ DEPENDENCIES
mutant-rspec (= 0.11.22)
pg
rails_event_store!
rails_event_store_active_record!
rake (>= 10.0)
rspec (~> 3.6)
rspec-rails
Expand Down
2 changes: 1 addition & 1 deletion contrib/ruby_event_store-outbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ In your event store configuration, as a dispatcher use `RubyEventStore::Immediat
```ruby

RailsEventStore::Client.new(
dispatcher: RailsEventStore::ImmediateAsyncDispatcher.new(scheduler: RubyEventStore::Outbox::SidekiqScheduler.new),
dispatcher: RailsEventStore::ImmediateDispatcher.new(scheduler: RubyEventStore::Outbox::SidekiqScheduler.new),
...
)
```
Expand Down
2 changes: 1 addition & 1 deletion contrib/ruby_event_store-profiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ event_store =
RubyEventStore::Client.new(
repository: RubyEventStore::InstrumentedRepository.new(RubyEventStore::InMemoryRepository.new, instrumenter),
mapper: RubyEventStore::Mappers::InstrumentedMapper.new(RubyEventStore::Mappers::Default.new, instrumenter),
dispatcher: RubyEventStore::InstrumentedDispatcher.new(RubyEventStore::Dispatcher.new, instrumenter),
dispatcher: RubyEventStore::InstrumentedDispatcher.new(RubyEventStore::SyncScheduler.new, instrumenter),
)

repository = AggregateRoot::InstrumentedRepository.new(AggregateRoot::Repository.new(event_store), instrumenter)
Expand Down
2 changes: 1 addition & 1 deletion contrib/ruby_event_store-profiler/examples/demo
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ asn = ActiveSupport::Notifications
event_store = RubyEventStore::Client.new(
repository: RubyEventStore::InstrumentedRepository.new(RubyEventStore::InMemoryRepository.new, asn),
mapper: RubyEventStore::Mappers::InstrumentedMapper.new(RubyEventStore::Mappers::Default.new, asn),
dispatcher: RubyEventStore::InstrumentedDispatcher.new(RubyEventStore::Dispatcher.new, asn)
dispatcher: RubyEventStore::InstrumentedDispatcher.new(RubyEventStore::SyncScheduler.new, asn)
)
DummyEvent = Class.new(RubyEventStore::Event)
dummy = DummyEvent.new
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module RubyEventStore
class Profiler
METRICS = [/rails_event_store/, /aggregate_root/, "total"].freeze
METRICS = [/ruby_event_store/, /aggregate_root/, "total"].freeze
private_constant :METRICS

def initialize(instrumenter)
Expand Down
Loading