From fcf53c349558c2cad5737d09c311c6046137fb68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 01/59] Revert "Revert "PoC of double serialization prevention"" This reverts commit 9b5081e4a83a0a9f74306b16cec77138db812865. --- ruby_event_store-active_record/Gemfile | 1 + .../lib/ruby_event_store/active_record.rb | 1 + .../ruby_event_store/active_record/event.rb | 5 ++- .../active_record/pass_through.rb | 25 +++++++++++++ .../spec/passthrough_type_spec.rb | 37 +++++++++++++++++++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb create mode 100644 ruby_event_store-active_record/spec/passthrough_type_spec.rb diff --git a/ruby_event_store-active_record/Gemfile b/ruby_event_store-active_record/Gemfile index fb17e08762..3acd431ac0 100644 --- a/ruby_event_store-active_record/Gemfile +++ b/ruby_event_store-active_record/Gemfile @@ -7,3 +7,4 @@ eval_gemfile "../support/bundler/Gemfile.database" gem "ruby_event_store", path: ".." gem "childprocess" + diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb index d85bb08619..f97481aaa1 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb @@ -7,6 +7,7 @@ require_relative "active_record/generators/rails_event_id_index_migration_generator" require_relative "active_record/generators/foreign_key_on_event_id_migration_generator" require_relative "active_record/generators/rails_foreign_key_on_event_id_migration_generator" +require_relative "active_record/pass_through" require_relative "active_record/event" require_relative "active_record/with_default_models" require_relative "active_record/with_abstract_base_class" diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 0536d7c21b..0205ce7134 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -require "active_record" - module RubyEventStore module ActiveRecord class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" + + attribute :data, :pass_through + attribute :metadata, :pass_through end private_constant :Event diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb new file mode 100644 index 0000000000..e64e07bd69 --- /dev/null +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "active_record" + +module RubyEventStore + module ActiveRecord + class PassThrough < ::ActiveModel::Type::Value + include ::ActiveModel::Type::Helpers::Mutable + + def serialize(value) + value + end + + def deserialize(value) + value + end + + def type + :pass_through + end + end + end +end + +::ActiveRecord::Type.register(:pass_through, ::RubyEventStore::ActiveRecord::PassThrough) diff --git a/ruby_event_store-active_record/spec/passthrough_type_spec.rb b/ruby_event_store-active_record/spec/passthrough_type_spec.rb new file mode 100644 index 0000000000..ebfc151908 --- /dev/null +++ b/ruby_event_store-active_record/spec/passthrough_type_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "spec_helper" +require "ruby_event_store" +require "ruby_event_store/spec/event_repository_lint" + +module RubyEventStore + module ActiveRecord + ::RSpec.describe "PassThrough" do + helper = SpecHelper.new + mk_repository = -> { EventRepository.new(serializer: JSON) } + + let(:repository) { mk_repository.call } + let(:specification) do + RubyEventStore::Specification.new( + RubyEventStore::SpecificationReader.new(repository, RubyEventStore::Mappers::NullMapper.new) + ) + end + + around(:each) { |example| helper.run_lifecycle { example.run } } + + specify do + repository.append_to_stream( + [RubyEventStore::SRecord.new(data: { "foo" => "bar" })], + RubyEventStore::Stream.new("stream"), + RubyEventStore::ExpectedVersion.auto + ) + + record = repository.read(specification.result).first + expect(record.data).to eq({ "foo" => "bar" }) + expect( + ::ActiveRecord::Base.connection.execute("SELECT data ->> 'foo' as foo FROM event_store_events").first["foo"] + ).to eq("bar") + end + end if ENV["DATABASE_URL"].include?("postgres") + end +end From 2749fb2cbadc2296a0a29efb1255782152089df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 02/59] Revert "Revert "Pick correct serializer when testing"" This reverts commit bda28e04218fd0ef68a9e60e7f3b99d689e5680e. --- .../spec/pg_linearized_event_repository_spec.rb | 2 +- ruby_event_store-active_record/spec/spec_helper.rb | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ruby_event_store-active_record/spec/pg_linearized_event_repository_spec.rb b/ruby_event_store-active_record/spec/pg_linearized_event_repository_spec.rb index 9ab59ab1f5..2a6db64079 100644 --- a/ruby_event_store-active_record/spec/pg_linearized_event_repository_spec.rb +++ b/ruby_event_store-active_record/spec/pg_linearized_event_repository_spec.rb @@ -6,7 +6,7 @@ module RubyEventStore module ActiveRecord ::RSpec.describe PgLinearizedEventRepository do helper = SpecHelper.new - mk_repository = -> { PgLinearizedEventRepository.new(serializer: Serializers::YAML) } + mk_repository = -> { PgLinearizedEventRepository.new(serializer: helper.serializer) } it_behaves_like :event_repository, mk_repository, helper diff --git a/ruby_event_store-active_record/spec/spec_helper.rb b/ruby_event_store-active_record/spec/spec_helper.rb index c62ae47498..97d2047b01 100644 --- a/ruby_event_store-active_record/spec/spec_helper.rb +++ b/ruby_event_store-active_record/spec/spec_helper.rb @@ -16,7 +16,12 @@ class SpecHelper include SchemaHelper def serializer - Serializers::YAML + case ENV["DATA_TYPE"] + when /json/ + JSON + else + Serializers::YAML + end end def run_lifecycle From d46f9e3a55f17b3048f724051fefa2ac68c2fc24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 03/59] Revert "Revert "Less is more"" This reverts commit fcaa701bb8f48ad9cdede6c6f7efdd3df7f00432. --- .../lib/ruby_event_store/active_record/event.rb | 4 ++-- .../lib/ruby_event_store/active_record/pass_through.rb | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 0205ce7134..1792023d3d 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -6,8 +6,8 @@ class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - attribute :data, :pass_through - attribute :metadata, :pass_through + attribute :data, PassThrough.new + attribute :metadata, PassThrough.new end private_constant :Event diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb index e64e07bd69..86555a67ec 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb @@ -4,9 +4,7 @@ module RubyEventStore module ActiveRecord - class PassThrough < ::ActiveModel::Type::Value - include ::ActiveModel::Type::Helpers::Mutable - + class PassThrough < ::ActiveRecord::Type::Value def serialize(value) value end @@ -14,12 +12,6 @@ def serialize(value) def deserialize(value) value end - - def type - :pass_through - end end end end - -::ActiveRecord::Type.register(:pass_through, ::RubyEventStore::ActiveRecord::PassThrough) From 71b22bb41d6d99fe5daafe2ebe9b14c4dc3b83da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 04/59] Revert "Revert "Requirements for different column types"" This reverts commit db1b1973733298ec1fb4318e685fc2609a7cf4cf. --- .../spec/passthrough_type_spec.rb | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/ruby_event_store-active_record/spec/passthrough_type_spec.rb b/ruby_event_store-active_record/spec/passthrough_type_spec.rb index ebfc151908..1fba8e7888 100644 --- a/ruby_event_store-active_record/spec/passthrough_type_spec.rb +++ b/ruby_event_store-active_record/spec/passthrough_type_spec.rb @@ -29,9 +29,25 @@ module ActiveRecord record = repository.read(specification.result).first expect(record.data).to eq({ "foo" => "bar" }) expect( - ::ActiveRecord::Base.connection.execute("SELECT data ->> 'foo' as foo FROM event_store_events").first["foo"] + ::ActiveRecord::Base + .connection + .execute("SELECT data ->> 'foo' as foo FROM event_store_events ORDER BY created_at DESC") + .first[ + "foo" + ] ).to eq("bar") + end if ENV["DATABASE_URL"].include?("postgres") && %w[json jsonb].include?(ENV["DATA_TYPE"]) + + specify do + repository.append_to_stream( + [RubyEventStore::SRecord.new(data: { "foo" => "bar" })], + RubyEventStore::Stream.new("stream"), + RubyEventStore::ExpectedVersion.auto + ) + + record = repository.read(specification.result).first + expect(record.data).to eq({ "foo" => "bar" }) end - end if ENV["DATABASE_URL"].include?("postgres") + end end end From 2d21505b076444ab081d62df1cf92afe69b134c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 05/59] Revert "Revert "We don't introduce anything new over Value here"" This reverts commit 101540de8b97c9ede30f82d4fc94adf909632e4e. --- .../lib/ruby_event_store/active_record.rb | 1 - .../lib/ruby_event_store/active_record/event.rb | 6 ++++-- .../active_record/pass_through.rb | 17 ----------------- 3 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb index f97481aaa1..d85bb08619 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb @@ -7,7 +7,6 @@ require_relative "active_record/generators/rails_event_id_index_migration_generator" require_relative "active_record/generators/foreign_key_on_event_id_migration_generator" require_relative "active_record/generators/rails_foreign_key_on_event_id_migration_generator" -require_relative "active_record/pass_through" require_relative "active_record/event" require_relative "active_record/with_default_models" require_relative "active_record/with_abstract_base_class" diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 1792023d3d..2aade54323 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -1,13 +1,15 @@ # frozen_string_literal: true +require "active_record" + module RubyEventStore module ActiveRecord class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - attribute :data, PassThrough.new - attribute :metadata, PassThrough.new + attribute :data, ActiveModel::Type::Value.new + attribute :metadata, ActiveModel::Type::Value.new end private_constant :Event diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb deleted file mode 100644 index 86555a67ec..0000000000 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/pass_through.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require "active_record" - -module RubyEventStore - module ActiveRecord - class PassThrough < ::ActiveRecord::Type::Value - def serialize(value) - value - end - - def deserialize(value) - value - end - end - end -end From a5319aea77d65fdd4a0e7c1d91b17c950ef4b109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 06/59] Revert "Revert "Big :brain: time"" This reverts commit ccc697e32b95503e6a085ee153644c9cfeb90636. --- .../ruby_event_store/active_record/event.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 2aade54323..144f4b6756 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -8,8 +8,22 @@ class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - attribute :data, ActiveModel::Type::Value.new - attribute :metadata, ActiveModel::Type::Value.new + attribute :data, + Proc.new { + if %i[json jsonb].include?(self.columns_hash["data"].type) + ActiveModel::Type::Value.new + else + ActiveModel::Type::Binary.new + end + } + attribute :metadata, + Proc.new { + if %i[json jsonb].include?(self.columns_hash["metadata"].type) + ActiveModel::Type::Value.new + else + ActiveModel::Type::Binary.new + end + } end private_constant :Event From 4339cd1949cc96d9fe03c037fc725ab377f6f167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 07/59] Revert "Revert "Boom, get proposed type for column from AR and act"" This reverts commit c8310c8c02267cefcdbd4444c63bdff0103beec3. --- .../ruby_event_store/active_record/event.rb | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 144f4b6756..2b8b91fd2b 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -8,22 +8,8 @@ class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - attribute :data, - Proc.new { - if %i[json jsonb].include?(self.columns_hash["data"].type) - ActiveModel::Type::Value.new - else - ActiveModel::Type::Binary.new - end - } - attribute :metadata, - Proc.new { - if %i[json jsonb].include?(self.columns_hash["metadata"].type) - ActiveModel::Type::Value.new - else - ActiveModel::Type::Binary.new - end - } + attribute :data, ->(type) { %i[json jsonb].include?(type.type) ? ActiveModel::Type::Value.new : type } + attribute :metadata, ->(type) { %i[json jsonb].include?(type.type) ? ActiveModel::Type::Value.new : type } end private_constant :Event From 68cd8e167400e312ee5de07d9b9510c342351873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 08/59] Revert "Revert "Extract to variable"" This reverts commit 4d1508fddbb0c0a5b12ec6449aed275c63cc74e5. --- .../lib/ruby_event_store/active_record/event.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 2b8b91fd2b..22bd4a04fe 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -8,8 +8,10 @@ class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - attribute :data, ->(type) { %i[json jsonb].include?(type.type) ? ActiveModel::Type::Value.new : type } - attribute :metadata, ->(type) { %i[json jsonb].include?(type.type) ? ActiveModel::Type::Value.new : type } + skip_json_serialization = ->(type) { %i[json jsonb].include?(type.type) ? ActiveModel::Type::Value.new : type } + + attribute :data, skip_json_serialization + attribute :metadata, skip_json_serialization end private_constant :Event From d3b9065660b17bc516f221dc70cdb4d615806525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 09/59] Revert "Revert "More meaningful naming"" This reverts commit b599d6ac2e1f7869ac6ca48f70b4922381b20d90. --- .../lib/ruby_event_store/active_record/event.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 22bd4a04fe..0b53e2dca2 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -8,7 +8,9 @@ class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - skip_json_serialization = ->(type) { %i[json jsonb].include?(type.type) ? ActiveModel::Type::Value.new : type } + skip_json_serialization = ->(initial_column_type) do + %i[json jsonb].include?(initial_column_type.type) ? ActiveModel::Type::Value.new : initial_column_type + end attribute :data, skip_json_serialization attribute :metadata, skip_json_serialization From a5ef54f862539caac76a8ef92116c1ecc7e5dd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 10/59] Revert "Revert "No idea how to achieve the same in Rails < 6.1"" This reverts commit b5a4e306630124fc8b9db01b836d0bc8da39c0d3. --- .../lib/ruby_event_store/active_record/event.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb index 0b53e2dca2..56eab9e396 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/event.rb @@ -8,12 +8,14 @@ class Event < ::ActiveRecord::Base self.primary_key = :id self.table_name = "event_store_events" - skip_json_serialization = ->(initial_column_type) do - %i[json jsonb].include?(initial_column_type.type) ? ActiveModel::Type::Value.new : initial_column_type - end + if Gem::Version.new(::ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.1.0") + skip_json_serialization = ->(initial_column_type) do + %i[json jsonb].include?(initial_column_type.type) ? ActiveModel::Type::Value.new : initial_column_type + end - attribute :data, skip_json_serialization - attribute :metadata, skip_json_serialization + attribute :data, skip_json_serialization + attribute :metadata, skip_json_serialization + end end private_constant :Event From 1cedb83731a46883041daf01ef1bc5ea02d22553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 11/59] Revert "Revert "Better describing what this test is for"" This reverts commit 83ca36d4432205f204eee03d38d64f8f175259f2. --- .../{passthrough_type_spec.rb => skip_ar_serialization_spec.rb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ruby_event_store-active_record/spec/{passthrough_type_spec.rb => skip_ar_serialization_spec.rb} (94%) diff --git a/ruby_event_store-active_record/spec/passthrough_type_spec.rb b/ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb similarity index 94% rename from ruby_event_store-active_record/spec/passthrough_type_spec.rb rename to ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb index 1fba8e7888..fb4bf2de13 100644 --- a/ruby_event_store-active_record/spec/passthrough_type_spec.rb +++ b/ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb @@ -6,7 +6,7 @@ module RubyEventStore module ActiveRecord - ::RSpec.describe "PassThrough" do + ::RSpec.describe "Skip ActiveRecord serialization of data and metadata for json(b) columns" do helper = SpecHelper.new mk_repository = -> { EventRepository.new(serializer: JSON) } From 5ec7afaaba8d710105aec6bd03f84052e753d301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Mon, 30 Jan 2023 11:47:32 +0100 Subject: [PATCH 12/59] Revert "Revert "Document how to use json in RES 3.0"" This reverts commit 310bdf85db561337aded63c19c7b4c4578e4cddf. --- railseventstore.org/config.rb | 1 + .../source/docs/v3/serialization.html.md.erb | 134 ++++++++++++++++++ .../source/partials/_documentation_nav_v3.erb | 21 +++ 3 files changed, 156 insertions(+) create mode 100644 railseventstore.org/source/docs/v3/serialization.html.md.erb create mode 100644 railseventstore.org/source/partials/_documentation_nav_v3.erb diff --git a/railseventstore.org/config.rb b/railseventstore.org/config.rb index 2bcc9fa79f..979a87e15c 100644 --- a/railseventstore.org/config.rb +++ b/railseventstore.org/config.rb @@ -39,4 +39,5 @@ def precompiled_template(locals) page "/" page "/docs/v1/*", locals: { version: "v1" }, layout: "documentation" page "/docs/v2/*", locals: { version: "v2" }, layout: "documentation" +page "/docs/v3/*", locals: { version: "v3" }, layout: "documentation" page "*", locals: { version: "v2" } diff --git a/railseventstore.org/source/docs/v3/serialization.html.md.erb b/railseventstore.org/source/docs/v3/serialization.html.md.erb new file mode 100644 index 0000000000..d90e8edab3 --- /dev/null +++ b/railseventstore.org/source/docs/v3/serialization.html.md.erb @@ -0,0 +1,134 @@ +--- +title: Event serialization formats +--- + +By default RailsEventStore will use `YAML` as a +serialization format. The reason is that `YAML` is available out of box +and can serialize and deserialize data types which are not easily +handled in other formats. + +However, if you don't like `YAML` or you have different needs you can +choose to use different serializers or even replace mappers entirely. + +## Configuring a different serializer + +You can pass a different `serializer` as a dependency when [instantiating +the client](/docs/v2/install). + +Here is an example on how to configure RailsEventStore to serialize +events' `data` and `metadata` using `Marshal`. + +```ruby +# config/environments/*.rb + +Rails.application.configure do + config.to_prepare do + Rails.configuration.event_store = RailsEventStore::Client.new( + repository: RailsEventStoreActiveRecord::EventRepository.new(serializer: Marshal) + ) + end +end +``` + +The provided `serializer` must respond to `load` and `dump`. + +Serialization is needed not only when writing to and reading from storage, but also when scheduling events for background processing by async handlers: + +```ruby +Rails.configuration.event_store = RailsEventStore::Client.new( + dispatcher: RubyEventStore::ComposedDispatcher.new( + RailsEventStore::AfterCommitAsyncDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: Marshal)), + RubyEventStore::Dispatcher.new + ) + ) +``` + +```ruby +class SomeHandler < ActiveJob::Base + include RailsEventStore::AsyncHandler.with(serializer: Marshal) + + def perform(event) + # ... + end +end +``` + +## Configuring for Postgres JSON/B data type + +In Postgres database, you can store your events data and metadata in json or jsonb format. + +To generate migration containing event table schemas run + +```console +$ rails generate rails_event_store_active_record:migration --data-type=jsonb +``` + +Next, in your `RailsEventStore::Client` initialization, set repository serialization to ` RailsEventStoreActiveRecord::EventRepository.new(serializer: JSON)` + +```ruby +# config/environments/*.rb + +Rails.application.configure do + config.to_prepare do + Rails.configuration.event_store = RailsEventStore::Client.new( + repository: RubyEventStore::ActiveRecord::EventRepository.new(serializer: JSON) + ) + end +end +``` + +Using the `JSON` serializer (or any compatible, e.g. `ActiveSupport::JSON`) will serialize the event data and metadata. +It will do otherwise when reading. +ActiveRecord serialization will be skipped. +Database itself expect data to be json already. + + diff --git a/railseventstore.org/source/partials/_documentation_nav_v3.erb b/railseventstore.org/source/partials/_documentation_nav_v3.erb new file mode 100644 index 0000000000..734110247a --- /dev/null +++ b/railseventstore.org/source/partials/_documentation_nav_v3.erb @@ -0,0 +1,21 @@ +

+ Getting started +

+
    +
+

+ Core concepts +

+
    +
+

+ Advanced topics +

+
    +
  • <%= sidebar_link_to "Event serialization formats", "/docs/v3/serialization/" %>
  • +
+

+ Common usage patterns +

+
    +
\ No newline at end of file From d0399e8de5e12a76fe2beee38bb4f2579d634854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Tue, 29 Nov 2022 10:53:21 +0100 Subject: [PATCH 13/59] Revert "Revert "Raise ArgumentError when trying to publish nil as event"" This reverts commit 95d9bc9c80ec81c201b63540e3065f5f603060b4. --- ruby_event_store/lib/ruby_event_store/client.rb | 4 ++++ ruby_event_store/spec/client_spec.rb | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ruby_event_store/lib/ruby_event_store/client.rb b/ruby_event_store/lib/ruby_event_store/client.rb index 0ed4217195..a42fdcf21d 100644 --- a/ruby_event_store/lib/ruby_event_store/client.rb +++ b/ruby_event_store/lib/ruby_event_store/client.rb @@ -343,12 +343,16 @@ def transform(events) end def enrich_events_metadata(events) + raise ArgumentError, "Event cannot be `nil`" if events.nil? + events = Array(events) events.each { |event| enrich_event_metadata(event) } events end def enrich_event_metadata(event) + raise ArgumentError, "Event cannot be `nil`" if event.nil? + metadata.each { |key, value| event.metadata[key] ||= value } event.metadata[:timestamp] ||= clock.call event.metadata[:valid_at] ||= event.metadata.fetch(:timestamp) diff --git a/ruby_event_store/spec/client_spec.rb b/ruby_event_store/spec/client_spec.rb index ee3b4fe39f..3f96dc5ed3 100644 --- a/ruby_event_store/spec/client_spec.rb +++ b/ruby_event_store/spec/client_spec.rb @@ -13,6 +13,20 @@ module RubyEventStore expect(client.publish(TestEvent.new)).to eq(client) end + specify "publish with no events, fail if nil" do + client.append([], stream_name: stream) + + expect { + client.publish(nil, stream_name: stream) + }.to raise_error(ArgumentError, "Event cannot be `nil`") + + expect { + client.publish([nil], stream_name: stream) + }.to raise_error(ArgumentError, "Event cannot be `nil`") + + expect(client.read.stream(stream).to_a).to be_empty + end + specify "append returns client when success" do expect(client.append(TestEvent.new, stream_name: stream)).to eq(client) end @@ -192,7 +206,7 @@ module RubyEventStore expect(published[2].metadata[:valid_at]).to be_a Time end - specify "event's metadata takes precedence over with_metadata" do + specify "event's metadata takes precedence over with_metadata" do client.with_metadata(request_ip: "127.0.0.1") do client.publish(@event = TestEvent.new(metadata: { request_ip: "1.2.3.4" })) end From 3c2414f9bfb31a3d1062dd75554558c784814092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Tue, 29 Nov 2022 10:53:21 +0100 Subject: [PATCH 14/59] Revert "Revert "Extract assertion to separate method and call it asap"" This reverts commit 12d73305a755912a4542404b7d6c4044865f5b8b. --- ruby_event_store/lib/ruby_event_store/client.rb | 14 ++++++++++---- ruby_event_store/spec/client_spec.rb | 16 +++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/client.rb b/ruby_event_store/lib/ruby_event_store/client.rb index a42fdcf21d..645915a49c 100644 --- a/ruby_event_store/lib/ruby_event_store/client.rb +++ b/ruby_event_store/lib/ruby_event_store/client.rb @@ -30,6 +30,8 @@ def initialize( # @param expected_version [:any, :auto, :none, Integer] controls optimistic locking strategy. {http://railseventstore.org/docs/expected_version/ Read more} # @return [self] def publish(events, stream_name: GLOBAL_STREAM, expected_version: :any) + assert_nil_events(events) + enriched_events = enrich_events_metadata(events) records = transform(enriched_events) append_records_to_stream(records, stream_name: stream_name, expected_version: expected_version) @@ -46,6 +48,8 @@ def publish(events, stream_name: GLOBAL_STREAM, expected_version: :any) # @param (see #publish) # @return [self] def append(events, stream_name: GLOBAL_STREAM, expected_version: :any) + assert_nil_events(events) + append_records_to_stream( transform(enrich_events_metadata(events)), stream_name: stream_name, @@ -338,21 +342,23 @@ def inspect private + def assert_nil_events(events) + raise ArgumentError, "Event cannot be `nil`" if events.nil? + events = Array(events) + raise ArgumentError, "Event cannot be `nil`" if events.any?(&:nil?) + end + def transform(events) events.map { |ev| mapper.event_to_record(ev) } end def enrich_events_metadata(events) - raise ArgumentError, "Event cannot be `nil`" if events.nil? - events = Array(events) events.each { |event| enrich_event_metadata(event) } events end def enrich_event_metadata(event) - raise ArgumentError, "Event cannot be `nil`" if event.nil? - metadata.each { |key, value| event.metadata[key] ||= value } event.metadata[:timestamp] ||= clock.call event.metadata[:valid_at] ||= event.metadata.fetch(:timestamp) diff --git a/ruby_event_store/spec/client_spec.rb b/ruby_event_store/spec/client_spec.rb index 3f96dc5ed3..fb51f9325e 100644 --- a/ruby_event_store/spec/client_spec.rb +++ b/ruby_event_store/spec/client_spec.rb @@ -14,7 +14,7 @@ module RubyEventStore end specify "publish with no events, fail if nil" do - client.append([], stream_name: stream) + client.publish([], stream_name: stream) expect { client.publish(nil, stream_name: stream) @@ -31,6 +31,20 @@ module RubyEventStore expect(client.append(TestEvent.new, stream_name: stream)).to eq(client) end + specify "append with no events, fail if nil" do + client.append([], stream_name: stream) + + expect { + client.append(nil, stream_name: stream) + }.to raise_error(ArgumentError, "Event cannot be `nil`") + + expect { + client.append([nil], stream_name: stream) + }.to raise_error(ArgumentError, "Event cannot be `nil`") + + expect(client.read.stream(stream).to_a).to be_empty + end + specify "append to default stream when not specified" do expect(client.append(test_event = TestEvent.new)).to eq(client) expect(client.read.limit(100).to_a).to eq([test_event]) From fa5bb0eec73a615ec324995dc5e9e9f6ff9d3b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Tue, 29 Nov 2022 10:53:21 +0100 Subject: [PATCH 15/59] Revert "Revert "Assert nil when linking events"" This reverts commit 9ee7904314d1907e9f6e7c6d6a16e6c8fe10e0cf. --- .../lib/ruby_event_store/client.rb | 2 ++ ruby_event_store/spec/client_spec.rb | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ruby_event_store/lib/ruby_event_store/client.rb b/ruby_event_store/lib/ruby_event_store/client.rb index 645915a49c..354c3ea7cc 100644 --- a/ruby_event_store/lib/ruby_event_store/client.rb +++ b/ruby_event_store/lib/ruby_event_store/client.rb @@ -66,6 +66,8 @@ def append(events, stream_name: GLOBAL_STREAM, expected_version: :any) # @param expected_version (see #publish) # @return [self] def link(event_ids, stream_name:, expected_version: :any) + assert_nil_events(event_ids) + repository.link_to_stream(Array(event_ids), Stream.new(stream_name), ExpectedVersion.new(expected_version)) self end diff --git a/ruby_event_store/spec/client_spec.rb b/ruby_event_store/spec/client_spec.rb index fb51f9325e..aab457ef5b 100644 --- a/ruby_event_store/spec/client_spec.rb +++ b/ruby_event_store/spec/client_spec.rb @@ -45,6 +45,25 @@ module RubyEventStore expect(client.read.stream(stream).to_a).to be_empty end + specify "link returns self when success" do + client.append(event = TestEvent.new) + expect(client.link(event.event_id, stream_name: stream)).to eq(client) + end + + specify "link with no events, fail if nil" do + client.link([], stream_name: stream) + + expect { + client.link(nil, stream_name: stream) + }.to raise_error(ArgumentError, "Event cannot be `nil`") + + expect { + client.link([nil], stream_name: stream) + }.to raise_error(ArgumentError, "Event cannot be `nil`") + + expect(client.read.stream(stream).to_a).to be_empty + end + specify "append to default stream when not specified" do expect(client.append(test_event = TestEvent.new)).to eq(client) expect(client.read.limit(100).to_a).to eq([test_event]) From 8cffd224bb47847dda984942b01113188c422679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Thu, 8 Dec 2022 22:44:32 +0100 Subject: [PATCH 16/59] Revert "Remove rename warning" This reverts commit b76e96cbdaed51bffe263cbfbf8dbc0bdc200941. --- .../lib/rails_event_store_active_record.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ruby_event_store-active_record/lib/rails_event_store_active_record.rb b/ruby_event_store-active_record/lib/rails_event_store_active_record.rb index e3e9e3a5fd..58f1539e70 100644 --- a/ruby_event_store-active_record/lib/rails_event_store_active_record.rb +++ b/ruby_event_store-active_record/lib/rails_event_store_active_record.rb @@ -1,3 +1,13 @@ require "ruby_event_store/active_record" +warn <<~EOW + The 'rails_event_store_active_record' gem has been renamed. + + Please change your Gemfile or gemspec + to reflect its new name: + + 'ruby_event_store-active_record' + +EOW + RailsEventStoreActiveRecord = RubyEventStore::ActiveRecord From 55d674e79ef78cbb28dcaa3fbd1d059dfc310491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Thu, 8 Dec 2022 22:45:40 +0100 Subject: [PATCH 17/59] Revert "Kill mutants" This reverts commit 11157edebeb85e736ef963af0c3f3ba1fa24846a. --- .../spec/migration_generator_spec.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {ruby_event_store-active_record => rails_event_store}/spec/migration_generator_spec.rb (100%) diff --git a/ruby_event_store-active_record/spec/migration_generator_spec.rb b/rails_event_store/spec/migration_generator_spec.rb similarity index 100% rename from ruby_event_store-active_record/spec/migration_generator_spec.rb rename to rails_event_store/spec/migration_generator_spec.rb From 1e39596fd94c717db5bd0661c072aa4e33c821e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Thu, 8 Dec 2022 22:51:12 +0100 Subject: [PATCH 18/59] Revert "RailsEventStore 2.6.X should point to RailsEventStoreActiveRecord" This reverts commit e847fac91f5a69c098373d1925a908c46aab8ce5. --- contrib/dres_rails/Gemfile | 1 - contrib/ruby_event_store-protobuf/Gemfile | 1 - rails_event_store/Gemfile | 1 - rails_event_store/Gemfile.lock | 1 - rails_event_store/Gemfile.rails_6_0 | 1 - rails_event_store/Gemfile.rails_6_0.lock | 1 - rails_event_store/Gemfile.rails_6_1 | 1 - rails_event_store/Gemfile.rails_6_1.lock | 1 - rails_event_store/lib/rails_event_store.rb | 2 +- rails_event_store/spec/dummy_6_0/Gemfile | 1 - rails_event_store/spec/dummy_6_0/Gemfile.lock | 1 - rails_event_store/spec/dummy_6_1/Gemfile | 1 - rails_event_store/spec/dummy_6_1/Gemfile.lock | 1 - rails_event_store/spec/dummy_7_0/Gemfile | 1 - rails_event_store/spec/dummy_7_0/Gemfile.lock | 1 - 15 files changed, 1 insertion(+), 15 deletions(-) diff --git a/contrib/dres_rails/Gemfile b/contrib/dres_rails/Gemfile index 9da8a29a5b..a67f69f739 100644 --- a/contrib/dres_rails/Gemfile +++ b/contrib/dres_rails/Gemfile @@ -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" diff --git a/contrib/ruby_event_store-protobuf/Gemfile b/contrib/ruby_event_store-protobuf/Gemfile index 8b839c76b5..12e0b0919a 100644 --- a/contrib/ruby_event_store-protobuf/Gemfile +++ b/contrib/ruby_event_store-protobuf/Gemfile @@ -7,7 +7,6 @@ gem "ruby_event_store", path: "../.." gem "aggregate_root", path: "../.." gem "rails_event_store", path: "../.." gem "ruby_event_store-active_record", path: "../.." -gem "rails_event_store_active_record", path: "../.." gem "ruby_event_store-browser", path: "../.." gem "protobuf_nested_struct" diff --git a/rails_event_store/Gemfile b/rails_event_store/Gemfile index 9f0b8ca73c..eba9e23c9d 100644 --- a/rails_event_store/Gemfile +++ b/rails_event_store/Gemfile @@ -6,7 +6,6 @@ eval_gemfile "../support/bundler/Gemfile.shared" gem "ruby_event_store", path: ".." gem "ruby_event_store-browser", path: ".." gem "ruby_event_store-active_record", path: ".." -gem "rails_event_store_active_record", path: ".." gem "aggregate_root", path: ".." gem "sidekiq" diff --git a/rails_event_store/Gemfile.lock b/rails_event_store/Gemfile.lock index 821a820718..77fdfd67be 100644 --- a/rails_event_store/Gemfile.lock +++ b/rails_event_store/Gemfile.lock @@ -249,7 +249,6 @@ DEPENDENCIES rack-test rails (~> 7.0.7) rails_event_store! - rails_event_store_active_record! rake (>= 10.0) rspec (~> 3.6) ruby_event_store! diff --git a/rails_event_store/Gemfile.rails_6_0 b/rails_event_store/Gemfile.rails_6_0 index daf8a685da..6a2c9a6c14 100644 --- a/rails_event_store/Gemfile.rails_6_0 +++ b/rails_event_store/Gemfile.rails_6_0 @@ -6,7 +6,6 @@ eval_gemfile "../support/bundler/Gemfile.shared" gem "ruby_event_store", path: ".." gem "ruby_event_store-browser", path: ".." gem "ruby_event_store-active_record", path: ".." -gem "rails_event_store_active_record", path: ".." gem "aggregate_root", path: ".." gem "sidekiq" diff --git a/rails_event_store/Gemfile.rails_6_0.lock b/rails_event_store/Gemfile.rails_6_0.lock index b8a5c28898..cba23b4c07 100644 --- a/rails_event_store/Gemfile.rails_6_0.lock +++ b/rails_event_store/Gemfile.rails_6_0.lock @@ -247,7 +247,6 @@ DEPENDENCIES rack-test rails (~> 6.0.6) rails_event_store! - rails_event_store_active_record! rake (>= 10.0) rspec (~> 3.6) ruby_event_store! diff --git a/rails_event_store/Gemfile.rails_6_1 b/rails_event_store/Gemfile.rails_6_1 index f6b07c2806..942f9f2f2e 100644 --- a/rails_event_store/Gemfile.rails_6_1 +++ b/rails_event_store/Gemfile.rails_6_1 @@ -6,7 +6,6 @@ eval_gemfile "../support/bundler/Gemfile.shared" gem "ruby_event_store", path: ".." gem "ruby_event_store-browser", path: ".." gem "ruby_event_store-active_record", path: ".." -gem "rails_event_store_active_record", path: ".." gem "aggregate_root", path: ".." gem "sidekiq" diff --git a/rails_event_store/Gemfile.rails_6_1.lock b/rails_event_store/Gemfile.rails_6_1.lock index 9f497f1b5d..a8aa665154 100644 --- a/rails_event_store/Gemfile.rails_6_1.lock +++ b/rails_event_store/Gemfile.rails_6_1.lock @@ -250,7 +250,6 @@ DEPENDENCIES rack-test rails (~> 6.1.7) rails_event_store! - rails_event_store_active_record! rake (>= 10.0) rspec (~> 3.6) ruby_event_store! diff --git a/rails_event_store/lib/rails_event_store.rb b/rails_event_store/lib/rails_event_store.rb index 8ebeb44b37..3f9af5d76a 100644 --- a/rails_event_store/lib/rails_event_store.rb +++ b/rails_event_store/lib/rails_event_store.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true -require "rails_event_store_active_record" +require "ruby_event_store/active_record" require_relative "rails_event_store/all" diff --git a/rails_event_store/spec/dummy_6_0/Gemfile b/rails_event_store/spec/dummy_6_0/Gemfile index ec14e91477..58380cf3c5 100644 --- a/rails_event_store/spec/dummy_6_0/Gemfile +++ b/rails_event_store/spec/dummy_6_0/Gemfile @@ -4,7 +4,6 @@ gem "rails_event_store", path: "../../" gem "ruby_event_store", path: "../../../ruby_event_store" gem "ruby_event_store-browser", path: "../../../ruby_event_store-browser" gem "ruby_event_store-active_record", path: "../../../ruby_event_store-active_record" -gem "rails_event_store_active_record", path: "../../../ruby_event_store-active_record" gem "aggregate_root", path: "../../../aggregate_root" gem "rails", "~> 6.0.6" \ No newline at end of file diff --git a/rails_event_store/spec/dummy_6_0/Gemfile.lock b/rails_event_store/spec/dummy_6_0/Gemfile.lock index faad4fdfc0..0c8a382bbe 100644 --- a/rails_event_store/spec/dummy_6_0/Gemfile.lock +++ b/rails_event_store/spec/dummy_6_0/Gemfile.lock @@ -201,7 +201,6 @@ DEPENDENCIES aggregate_root! rails (~> 6.0.6) rails_event_store! - rails_event_store_active_record! ruby_event_store! ruby_event_store-active_record! ruby_event_store-browser! diff --git a/rails_event_store/spec/dummy_6_1/Gemfile b/rails_event_store/spec/dummy_6_1/Gemfile index 02d5c185dd..e5c0b71215 100644 --- a/rails_event_store/spec/dummy_6_1/Gemfile +++ b/rails_event_store/spec/dummy_6_1/Gemfile @@ -4,7 +4,6 @@ gem "rails_event_store", path: "../../" gem "ruby_event_store", path: "../../../ruby_event_store" gem "ruby_event_store-browser", path: "../../../ruby_event_store-browser" gem "ruby_event_store-active_record", path: "../../../ruby_event_store-active_record" -gem "rails_event_store_active_record", path: "../../../ruby_event_store-active_record" gem "aggregate_root", path: "../../../aggregate_root" gem "rails", "~> 6.1.7" \ No newline at end of file diff --git a/rails_event_store/spec/dummy_6_1/Gemfile.lock b/rails_event_store/spec/dummy_6_1/Gemfile.lock index cb46a1cadc..8ca723b343 100644 --- a/rails_event_store/spec/dummy_6_1/Gemfile.lock +++ b/rails_event_store/spec/dummy_6_1/Gemfile.lock @@ -204,7 +204,6 @@ DEPENDENCIES aggregate_root! rails (~> 6.1.7) rails_event_store! - rails_event_store_active_record! ruby_event_store! ruby_event_store-active_record! ruby_event_store-browser! diff --git a/rails_event_store/spec/dummy_7_0/Gemfile b/rails_event_store/spec/dummy_7_0/Gemfile index 7a5794a0a8..d7071a63eb 100644 --- a/rails_event_store/spec/dummy_7_0/Gemfile +++ b/rails_event_store/spec/dummy_7_0/Gemfile @@ -4,7 +4,6 @@ gem "rails_event_store", path: "../../" gem "ruby_event_store", path: "../../../ruby_event_store" gem "ruby_event_store-browser", path: "../../../ruby_event_store-browser" gem "ruby_event_store-active_record", path: "../../../ruby_event_store-active_record" -gem "rails_event_store_active_record", path: "../../../ruby_event_store-active_record" gem "aggregate_root", path: "../../../aggregate_root" gem "rails", "~> 7.0.7" \ No newline at end of file diff --git a/rails_event_store/spec/dummy_7_0/Gemfile.lock b/rails_event_store/spec/dummy_7_0/Gemfile.lock index 32adc128db..9b0f1791b6 100644 --- a/rails_event_store/spec/dummy_7_0/Gemfile.lock +++ b/rails_event_store/spec/dummy_7_0/Gemfile.lock @@ -198,7 +198,6 @@ DEPENDENCIES aggregate_root! rails (~> 7.0.7) rails_event_store! - rails_event_store_active_record! ruby_event_store! ruby_event_store-active_record! ruby_event_store-browser! From aefd664bd6ca8cac99d9b4e3b11380567f8e0afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Thu, 8 Dec 2022 22:52:09 +0100 Subject: [PATCH 19/59] Revert "Remove post install deprecation message for rails_event_store_active_record" This reverts commit 057e333e5d6fc3f82d9ba31dfbc8f4de846a8523. --- .../rails_event_store_active_record.gemspec | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ruby_event_store-active_record/rails_event_store_active_record.gemspec b/ruby_event_store-active_record/rails_event_store_active_record.gemspec index 5515f604cb..7740823c2d 100644 --- a/ruby_event_store-active_record/rails_event_store_active_record.gemspec +++ b/ruby_event_store-active_record/rails_event_store_active_record.gemspec @@ -30,4 +30,13 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 2.7" spec.add_dependency "ruby_event_store-active_record", RubyEventStore::ActiveRecord::VERSION + spec.post_install_message = <<~EOW + The 'rails_event_store_active_record' gem has been renamed. + + Please change your Gemfile or gemspec + to reflect its new name: + + 'ruby_event_store-active-record' + + EOW end From 5acd7dfbe32c8c7c6be428b8f9b86162b001ebb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20=C5=81asocha?= Date: Mon, 26 Jul 2021 14:34:25 +0200 Subject: [PATCH 20/59] Ensure only supported any usage by default Breaks backwards compatibility, so to be merged with RES 3.x. We may also consider adding some configuration option to turn it off. --- .../lib/ruby_event_store/in_memory_repository.rb | 2 +- ruby_event_store/spec/in_memory_repository_spec.rb | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/in_memory_repository.rb b/ruby_event_store/lib/ruby_event_store/in_memory_repository.rb index 3549d23373..bbd9f14d9c 100644 --- a/ruby_event_store/lib/ruby_event_store/in_memory_repository.rb +++ b/ruby_event_store/lib/ruby_event_store/in_memory_repository.rb @@ -23,7 +23,7 @@ def initialize(event_id, position) attr_reader :event_id, :position end - def initialize(serializer: NULL, ensure_supported_any_usage: false) + def initialize(serializer: NULL, ensure_supported_any_usage: true) @serializer = serializer @streams = Hash.new { |h, k| h[k] = Array.new } @mutex = Mutex.new diff --git a/ruby_event_store/spec/in_memory_repository_spec.rb b/ruby_event_store/spec/in_memory_repository_spec.rb index 277d91844e..8786a7dc46 100644 --- a/ruby_event_store/spec/in_memory_repository_spec.rb +++ b/ruby_event_store/spec/in_memory_repository_spec.rb @@ -140,13 +140,5 @@ module RubyEventStore repository.append_to_stream([event1 = SRecord.new], Stream.new("stream"), ExpectedVersion.auto) end.not_to raise_error end - - it "stream position verification is turned off by default" do - repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.auto) - - expect do - repository.append_to_stream([event1 = SRecord.new], Stream.new("stream"), ExpectedVersion.any) - end.not_to raise_error - end end end From 81d7a47f867018e17f15681f6a8526cca727c3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miros=C5=82aw=20Prag=C5=82owski?= Date: Tue, 5 Jan 2021 13:07:29 +0100 Subject: [PATCH 21/59] No more aggregate root configuration Since we have introduced AggregateRoot::Repository it is easy to pass event store as a dependency there. No need to use AggregateRoot::Configuration and default_event_store. Make it explicte which event store is used. Less "magic". --- aggregate_root/lib/aggregate_root.rb | 1 - .../lib/aggregate_root/configuration.rb | 16 --------- .../lib/aggregate_root/repository.rb | 6 +--- aggregate_root/spec/repository_spec.rb | 35 ------------------- aggregate_root/spec/spec_helper.rb | 2 -- 5 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 aggregate_root/lib/aggregate_root/configuration.rb diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index 87a1bd3bde..7407c2a6fc 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -1,7 +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" diff --git a/aggregate_root/lib/aggregate_root/configuration.rb b/aggregate_root/lib/aggregate_root/configuration.rb deleted file mode 100644 index 6935658048..0000000000 --- a/aggregate_root/lib/aggregate_root/configuration.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module AggregateRoot - class << self - attr_accessor :configuration - end - - def self.configure - self.configuration ||= Configuration.new - yield(configuration) - end - - class Configuration - attr_accessor :default_event_store - end -end diff --git a/aggregate_root/lib/aggregate_root/repository.rb b/aggregate_root/lib/aggregate_root/repository.rb index ad73120d43..09e2ea9575 100644 --- a/aggregate_root/lib/aggregate_root/repository.rb +++ b/aggregate_root/lib/aggregate_root/repository.rb @@ -2,7 +2,7 @@ module AggregateRoot class Repository - def initialize(event_store = default_event_store) + def initialize(event_store) @event_store = event_store end @@ -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 diff --git a/aggregate_root/spec/repository_spec.rb b/aggregate_root/spec/repository_spec.rb index e388667f2d..f7ea3c7d46 100644 --- a/aggregate_root/spec/repository_spec.rb +++ b/aggregate_root/spec/repository_spec.rb @@ -39,41 +39,6 @@ def apply_order_expired(_event) 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) diff --git a/aggregate_root/spec/spec_helper.rb b/aggregate_root/spec/spec_helper.rb index 70dab3ce72..22e40dfcf1 100644 --- a/aggregate_root/spec/spec_helper.rb +++ b/aggregate_root/spec/spec_helper.rb @@ -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) From 9bbac9bdb47c76a4fe52c3be1f67f64b8d9fe807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miros=C5=82aw=20Prag=C5=82owski?= Date: Tue, 5 Jan 2021 15:01:57 +0100 Subject: [PATCH 22/59] Remove deprecated JSONMapper --- ruby_event_store/lib/ruby_event_store.rb | 1 - .../ruby_event_store/mappers/json_mapper.rb | 16 ---------------- .../spec/mappers/json_mapper_spec.rb | 18 ------------------ 3 files changed, 35 deletions(-) delete mode 100644 ruby_event_store/lib/ruby_event_store/mappers/json_mapper.rb delete mode 100644 ruby_event_store/spec/mappers/json_mapper_spec.rb diff --git a/ruby_event_store/lib/ruby_event_store.rb b/ruby_event_store/lib/ruby_event_store.rb index 50be5761f7..06245fc831 100644 --- a/ruby_event_store/lib/ruby_event_store.rb +++ b/ruby_event_store/lib/ruby_event_store.rb @@ -34,7 +34,6 @@ require_relative "ruby_event_store/mappers/forgotten_data" require_relative "ruby_event_store/mappers/encryption_mapper" require_relative "ruby_event_store/mappers/instrumented_mapper" -require_relative "ruby_event_store/mappers/json_mapper" require_relative "ruby_event_store/mappers/null_mapper" require_relative "ruby_event_store/serializers/yaml" require_relative "ruby_event_store/batch_enumerator" diff --git a/ruby_event_store/lib/ruby_event_store/mappers/json_mapper.rb b/ruby_event_store/lib/ruby_event_store/mappers/json_mapper.rb deleted file mode 100644 index 93f64773d0..0000000000 --- a/ruby_event_store/lib/ruby_event_store/mappers/json_mapper.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module RubyEventStore - module Mappers - class JSONMapper < Default - def initialize(events_class_remapping: {}) - warn <<~EOW - Please replace RubyEventStore::Mappers::JSONMapper with RubyEventStore::Mappers::Default - - They're now identical and the former will be removed in next major release. - EOW - super - end - end - end -end diff --git a/ruby_event_store/spec/mappers/json_mapper_spec.rb b/ruby_event_store/spec/mappers/json_mapper_spec.rb deleted file mode 100644 index 0a4f414c3d..0000000000 --- a/ruby_event_store/spec/mappers/json_mapper_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "ruby_event_store/spec/mapper_lint" - -SomethingHappenedJSON = Class.new(RubyEventStore::Event) - -module RubyEventStore - module Mappers - ::RSpec.describe JSONMapper do - specify { expect { JSONMapper.new }.to output(<<~EOW).to_stderr } - Please replace RubyEventStore::Mappers::JSONMapper with RubyEventStore::Mappers::Default - - They're now identical and the former will be removed in next major release. - EOW - end - end -end From 42b477a492d2f4edef20136fa1abdfc8135d1afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Sat, 9 Jan 2021 11:59:09 +0100 Subject: [PATCH 23/59] NullMapper no longer makes sense without serilizaion in mappers --- .../spec/skip_ar_serialization_spec.rb | 2 +- ruby_event_store/lib/ruby_event_store.rb | 3 +- .../ruby_event_store/mappers/null_mapper.rb | 11 ----- .../spec/mappers/null_mapper_spec.rb | 46 ------------------- 4 files changed, 2 insertions(+), 60 deletions(-) delete mode 100644 ruby_event_store/lib/ruby_event_store/mappers/null_mapper.rb delete mode 100644 ruby_event_store/spec/mappers/null_mapper_spec.rb diff --git a/ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb b/ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb index fb4bf2de13..c8e6ee067a 100644 --- a/ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb +++ b/ruby_event_store-active_record/spec/skip_ar_serialization_spec.rb @@ -13,7 +13,7 @@ module ActiveRecord let(:repository) { mk_repository.call } let(:specification) do RubyEventStore::Specification.new( - RubyEventStore::SpecificationReader.new(repository, RubyEventStore::Mappers::NullMapper.new) + RubyEventStore::SpecificationReader.new(repository, RubyEventStore::Mappers::Default.new) ) end diff --git a/ruby_event_store/lib/ruby_event_store.rb b/ruby_event_store/lib/ruby_event_store.rb index 06245fc831..a3da1050e5 100644 --- a/ruby_event_store/lib/ruby_event_store.rb +++ b/ruby_event_store/lib/ruby_event_store.rb @@ -34,7 +34,6 @@ require_relative "ruby_event_store/mappers/forgotten_data" require_relative "ruby_event_store/mappers/encryption_mapper" require_relative "ruby_event_store/mappers/instrumented_mapper" -require_relative "ruby_event_store/mappers/null_mapper" require_relative "ruby_event_store/serializers/yaml" require_relative "ruby_event_store/batch_enumerator" require_relative "ruby_event_store/correlated_commands" @@ -45,4 +44,4 @@ require_relative "ruby_event_store/instrumented_repository" require_relative "ruby_event_store/instrumented_dispatcher" require_relative "ruby_event_store/instrumented_subscriptions" -require_relative "ruby_event_store/event_type_resolver" \ No newline at end of file +require_relative "ruby_event_store/event_type_resolver" diff --git a/ruby_event_store/lib/ruby_event_store/mappers/null_mapper.rb b/ruby_event_store/lib/ruby_event_store/mappers/null_mapper.rb deleted file mode 100644 index 21f34b30df..0000000000 --- a/ruby_event_store/lib/ruby_event_store/mappers/null_mapper.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module RubyEventStore - module Mappers - class NullMapper < PipelineMapper - def initialize - super(Pipeline.new) - end - end - end -end diff --git a/ruby_event_store/spec/mappers/null_mapper_spec.rb b/ruby_event_store/spec/mappers/null_mapper_spec.rb deleted file mode 100644 index 762411fcfd..0000000000 --- a/ruby_event_store/spec/mappers/null_mapper_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require "spec_helper" -require "ruby_event_store/spec/mapper_lint" - -module RubyEventStore - module Mappers - ::RSpec.describe NullMapper do - let(:time) { Time.now.utc } - let(:data) { { some_attribute: 5 } } - let(:metadata) { { some_meta: 1 } } - let(:event_id) { SecureRandom.uuid } - let(:event) do - TimeEnrichment.with( - TestEvent.new(data: data, metadata: metadata, event_id: event_id), - timestamp: time, - valid_at: time - ) - end - - it_behaves_like :mapper, NullMapper.new, TimeEnrichment.with(TestEvent.new) - - specify "#event_to_record" do - record = subject.event_to_record(event) - - expect(record.event_id).to eq(event.event_id) - expect(record.data).to eq(event.data) - expect(record.metadata.to_h).to eq(metadata) - expect(record.event_type).to eq("TestEvent") - expect(record.timestamp).to eq(time) - expect(record.valid_at).to eq(time) - end - - specify "#record_to_event" do - record = subject.event_to_record(event) - event_ = subject.record_to_event(record) - - expect(event_).to eq(event) - expect(event_.event_id).to eq(event.event_id) - expect(event_.data).to eq(event.data) - expect(event_.metadata.to_h).to eq(event.metadata.to_h) - expect(event_.event_type).to eq("TestEvent") - expect(event_.metadata[:timestamp]).to eq(time) - expect(event_.metadata[:valid_at]).to eq(time) - end - end - end -end From 45552b4a320a10de33cfbfb2bf037e037744b52b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Sat, 9 Jan 2021 11:35:09 +0100 Subject: [PATCH 24/59] EventClassRemapping superseded by upcasting --- ruby_event_store/lib/ruby_event_store.rb | 1 - .../lib/ruby_event_store/mappers/default.rb | 11 ++---- .../transformation/event_class_remapper.rb | 32 --------------- ruby_event_store/spec/mappers/default_spec.rb | 19 --------- .../event_class_remapper_spec.rb | 39 ------------------- ruby_event_store/spec/projection_spec.rb | 24 ------------ 6 files changed, 4 insertions(+), 122 deletions(-) delete mode 100644 ruby_event_store/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb delete mode 100644 ruby_event_store/spec/mappers/transformation/event_class_remapper_spec.rb diff --git a/ruby_event_store/lib/ruby_event_store.rb b/ruby_event_store/lib/ruby_event_store.rb index a3da1050e5..8b3690640b 100644 --- a/ruby_event_store/lib/ruby_event_store.rb +++ b/ruby_event_store/lib/ruby_event_store.rb @@ -23,7 +23,6 @@ require_relative "ruby_event_store/mappers/in_memory_encryption_key_repository" require_relative "ruby_event_store/mappers/transformation/domain_event" require_relative "ruby_event_store/mappers/transformation/encryption" -require_relative "ruby_event_store/mappers/transformation/event_class_remapper" require_relative "ruby_event_store/mappers/transformation/upcast" require_relative "ruby_event_store/mappers/transformation/stringify_metadata_keys" require_relative "ruby_event_store/mappers/transformation/symbolize_metadata_keys" diff --git a/ruby_event_store/lib/ruby_event_store/mappers/default.rb b/ruby_event_store/lib/ruby_event_store/mappers/default.rb index 259fd8b555..70ffec09bb 100644 --- a/ruby_event_store/lib/ruby_event_store/mappers/default.rb +++ b/ruby_event_store/lib/ruby_event_store/mappers/default.rb @@ -3,13 +3,10 @@ module RubyEventStore module Mappers class Default < PipelineMapper - def initialize(events_class_remapping: {}) - super( - Pipeline.new( - Transformation::EventClassRemapper.new(events_class_remapping), - Transformation::SymbolizeMetadataKeys.new - ) - ) + def initialize + super(Pipeline.new( + Transformation::SymbolizeMetadataKeys.new, + )) end end end diff --git a/ruby_event_store/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb b/ruby_event_store/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb deleted file mode 100644 index 7f4084864d..0000000000 --- a/ruby_event_store/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module RubyEventStore - module Mappers - module Transformation - class EventClassRemapper - def initialize(class_map) - @class_map = class_map - end - - def dump(record) - record - end - - def load(record) - Record.new( - event_id: record.event_id, - event_type: class_map[record.event_type] || record.event_type, - data: record.data, - metadata: record.metadata, - timestamp: record.timestamp, - valid_at: record.valid_at - ) - end - - private - - attr_reader :class_map - end - end - end -end diff --git a/ruby_event_store/spec/mappers/default_spec.rb b/ruby_event_store/spec/mappers/default_spec.rb index aa5faae14d..471675d283 100644 --- a/ruby_event_store/spec/mappers/default_spec.rb +++ b/ruby_event_store/spec/mappers/default_spec.rb @@ -55,25 +55,6 @@ module Mappers expect(event_.metadata[:valid_at]).to eq(time) end - specify "#record_to_event its using events class remapping" do - subject = Default.new(events_class_remapping: { "EventNameBeforeRefactor" => "SomethingHappened" }) - record = - Record.new( - event_id: event.event_id, - data: { - some_attribute: 5 - }, - metadata: { - some_meta: 1 - }, - event_type: "EventNameBeforeRefactor", - timestamp: time, - valid_at: time - ) - event_ = subject.record_to_event(record) - expect(event_).to eq(event) - end - specify "metadata keys are symbolized" do record = Record.new( diff --git a/ruby_event_store/spec/mappers/transformation/event_class_remapper_spec.rb b/ruby_event_store/spec/mappers/transformation/event_class_remapper_spec.rb deleted file mode 100644 index 19a83ec1f8..0000000000 --- a/ruby_event_store/spec/mappers/transformation/event_class_remapper_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "spec_helper" - -module RubyEventStore - module Mappers - module Transformation - ::RSpec.describe EventClassRemapper do - let(:time) { Time.now.utc } - let(:uuid) { SecureRandom.uuid } - def record(event_type: "TestEvent") - Record.new( - event_id: uuid, - metadata: { - some: "meta" - }, - data: { - some: "value" - }, - event_type: event_type, - timestamp: time, - valid_at: time - ) - end - let(:changeable_record) { record(event_type: "EventNameBeforeRefactor") } - let(:changed_record) { record(event_type: "SomethingHappened") } - let(:class_map) { { "EventNameBeforeRefactor" => "SomethingHappened" } } - - specify "#dump" do - expect(EventClassRemapper.new(class_map).dump(record)).to eq(record) - expect(EventClassRemapper.new(class_map).dump(record)).to eq(record) - end - - specify "#load" do - expect(EventClassRemapper.new(class_map).load(record)).to eq(record) - expect(EventClassRemapper.new(class_map).load(changeable_record)).to eq(changed_record) - end - end - end - end -end diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index b004dff155..a1ec514431 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -309,29 +309,5 @@ module RubyEventStore expect(state).to eq({}) end - - specify "supports event class remapping" do - event_store = - Client.new( - mapper: Mappers::Default.new(events_class_remapping: { MoneyInvested.to_s => MoneyLost.to_s }) - ) - event_store.append(MoneyInvested.new(data: { amount: 1 })) - - balance = - Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when(MoneyLost, ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store) - expect(balance).to eq(total: 0) - - balance = - Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when([MoneyLost, MoneyInvested], ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store) - expect(balance).to eq(total: -1) - end end end From d685cfb7eb169bcc36aaac142e588a56a2bda834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 15 Jan 2021 19:42:37 +0100 Subject: [PATCH 25/59] No more aliases on RubyEventStore consts --- .../lib/rails_event_store/all.rb | 20 ------------------- .../spec/active_job_scheduler_spec.rb | 4 +--- rails_event_store/spec/client_spec.rb | 1 - 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/rails_event_store/lib/rails_event_store/all.rb b/rails_event_store/lib/rails_event_store/all.rb index a34890350d..0df18d71d5 100644 --- a/rails_event_store/lib/rails_event_store/all.rb +++ b/rails_event_store/lib/rails_event_store/all.rb @@ -11,23 +11,3 @@ require_relative "version" require_relative "railtie" require_relative "browser" - -module RailsEventStore - Event = RubyEventStore::Event - InMemoryRepository = RubyEventStore::InMemoryRepository - Subscriptions = RubyEventStore::Subscriptions - Projection = RubyEventStore::Projection - WrongExpectedEventVersion = RubyEventStore::WrongExpectedEventVersion - InvalidExpectedVersion = RubyEventStore::InvalidExpectedVersion - IncorrectStreamData = RubyEventStore::IncorrectStreamData - EventNotFound = RubyEventStore::EventNotFound - SubscriberNotExist = RubyEventStore::SubscriberNotExist - InvalidHandler = RubyEventStore::InvalidHandler - InvalidPageStart = RubyEventStore::InvalidPageStart - InvalidPageStop = RubyEventStore::InvalidPageStop - InvalidPageSize = RubyEventStore::InvalidPageSize - CorrelatedCommands = RubyEventStore::CorrelatedCommands - GLOBAL_STREAM = RubyEventStore::GLOBAL_STREAM - PAGE_SIZE = RubyEventStore::PAGE_SIZE - ImmediateAsyncDispatcher = RubyEventStore::ImmediateAsyncDispatcher -end diff --git a/rails_event_store/spec/active_job_scheduler_spec.rb b/rails_event_store/spec/active_job_scheduler_spec.rb index 9040cd5c9f..0a7444d0ec 100644 --- a/rails_event_store/spec/active_job_scheduler_spec.rb +++ b/rails_event_store/spec/active_job_scheduler_spec.rb @@ -23,9 +23,7 @@ module RailsEventStore it_behaves_like :scheduler, ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML) it_behaves_like :scheduler, ActiveJobScheduler.new(serializer: RubyEventStore::NULL) - let(:event) do - TimeEnrichment.with(Event.new(event_id: "83c3187f-84f6-4da7-8206-73af5aca7cc8"), timestamp: Time.utc(2019, 9, 30)) - end + let(:event) { TimeEnrichment.with(RubyEventStore::Event.new(event_id: "83c3187f-84f6-4da7-8206-73af5aca7cc8"), timestamp: Time.utc(2019, 9, 30)) } let(:record) { RubyEventStore::Mappers::Default.new.event_to_record(event) } describe "#verify" do diff --git a/rails_event_store/spec/client_spec.rb b/rails_event_store/spec/client_spec.rb index ba258e8b4d..c6f1be912f 100644 --- a/rails_event_store/spec/client_spec.rb +++ b/rails_event_store/spec/client_spec.rb @@ -48,7 +48,6 @@ module RailsEventStore specify "wraps mapper into instrumentation" do client = Client.new(repository: RubyEventStore::InMemoryRepository.new, mapper: RubyEventStore::Mappers::Default.new) - received_notifications = 0 ActiveSupport::Notifications.subscribe("serialize.mapper.rails_event_store") { received_notifications += 1 } From 6880ad51424515bfafd3d104cf5e99e7ff1bbfd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Sat, 9 Jan 2021 14:08:11 +0100 Subject: [PATCH 26/59] Get rid of dubious meta-apply method handlers * no sane way to support event type scheme for extract last part * no sane way to normalize every event type to method name --- aggregate_root/lib/aggregate_root.rb | 1 - .../aggregate_root/default_apply_strategy.rb | 31 ++++++++----------- .../lib/aggregate_root/transform.rb | 9 ------ aggregate_root/spec/aggregate_root_spec.rb | 22 ++++++------- .../spec/instrumented_repository_spec.rb | 4 +-- aggregate_root/spec/repository_spec.rb | 4 +-- aggregate_root/spec/transform_spec.rb | 13 -------- 7 files changed, 26 insertions(+), 58 deletions(-) delete mode 100644 aggregate_root/lib/aggregate_root/transform.rb delete mode 100644 aggregate_root/spec/transform_spec.rb diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index 7407c2a6fc..57bd9112c8 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require_relative "aggregate_root/version" -require_relative "aggregate_root/transform" require_relative "aggregate_root/default_apply_strategy" require_relative "aggregate_root/repository" require_relative "aggregate_root/instrumented_repository" diff --git a/aggregate_root/lib/aggregate_root/default_apply_strategy.rb b/aggregate_root/lib/aggregate_root/default_apply_strategy.rb index 3046aa2aeb..b7149f00ec 100644 --- a/aggregate_root/lib/aggregate_root/default_apply_strategy.rb +++ b/aggregate_root/lib/aggregate_root/default_apply_strategy.rb @@ -2,6 +2,7 @@ module AggregateRoot MissingHandler = Class.new(StandardError) + NullHandler = Proc.new {} class DefaultApplyStrategy def initialize(strict: true) @@ -9,30 +10,24 @@ def initialize(strict: true) 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 + lambda { |event| raise MissingHandler.new("Missing handler method on aggregate #{aggregate.class} for #{event_type}") } + else + NullHandler + end end attr_reader :strict, :on_methods diff --git a/aggregate_root/lib/aggregate_root/transform.rb b/aggregate_root/lib/aggregate_root/transform.rb deleted file mode 100644 index 6f996bbbeb..0000000000 --- a/aggregate_root/lib/aggregate_root/transform.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module AggregateRoot - class Transform - def self.to_snake_case(name) - name.gsub(/([A-Z])([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase - end - end -end diff --git a/aggregate_root/spec/aggregate_root_spec.rb b/aggregate_root/spec/aggregate_root_spec.rb index 5c1b8e4b75..4d288c49c0 100644 --- a/aggregate_root/spec/aggregate_root_spec.rb +++ b/aggregate_root/spec/aggregate_root_spec.rb @@ -26,11 +26,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 @@ -39,9 +39,8 @@ def apply_order_expired(_event) 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 @@ -51,6 +50,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 @@ -59,15 +64,6 @@ 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) }) } diff --git a/aggregate_root/spec/instrumented_repository_spec.rb b/aggregate_root/spec/instrumented_repository_spec.rb index 344723482f..2a212d89fb 100644 --- a/aggregate_root/spec/instrumented_repository_spec.rb +++ b/aggregate_root/spec/instrumented_repository_spec.rb @@ -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 diff --git a/aggregate_root/spec/repository_spec.rb b/aggregate_root/spec/repository_spec.rb index f7ea3c7d46..690d057f5e 100644 --- a/aggregate_root/spec/repository_spec.rb +++ b/aggregate_root/spec/repository_spec.rb @@ -29,11 +29,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 diff --git a/aggregate_root/spec/transform_spec.rb b/aggregate_root/spec/transform_spec.rb deleted file mode 100644 index 8462b2a14b..0000000000 --- a/aggregate_root/spec/transform_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module AggregateRoot - ::RSpec.describe Transform do - specify { expect(Transform.to_snake_case("OrderSubmitted")).to eq("order_submitted") } - specify { expect(Transform.to_snake_case("OrderSubmittedMultipleTimesReally")).to eq("order_submitted_multiple_times_really") } - specify { expect(Transform.to_snake_case("SHA1ChecksumComputed")).to eq("sha1_checksum_computed") } - specify { expect(Transform.to_snake_case("OKROfPSAInQ1Reached")).to eq("okr_of_psa_in_q1_reached") } - specify { expect(Transform.to_snake_case("EncryptedWithRot13")).to eq("encrypted_with_rot13") } - end -end From 165742d7e7cd8fdef3c405e8d7b7243d2d28fb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Sat, 9 Jan 2021 14:11:52 +0100 Subject: [PATCH 27/59] Poor way to ensure with_strategy(->{ Default }) has OnDSL --- aggregate_root/lib/aggregate_root.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index 57bd9112c8..c8d3157f54 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -79,7 +79,6 @@ def marshal_load(vars) def self.with_default_apply_strategy Module.new do def self.included(host_class) - host_class.extend OnDSL host_class.include AggregateRoot.with_strategy(-> { DefaultApplyStrategy.new }) end end @@ -88,7 +87,8 @@ def self.included(host_class) def self.with_strategy(strategy) Module.new do def self.included(host_class) - host_class.extend Constructor + host_class.extend OnDSL + host_class.extend Constructor host_class.include AggregateMethods end From dd7a7b2969f6d9b250565dec94279a282fdbf177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Sat, 9 Jan 2021 14:41:48 +0100 Subject: [PATCH 28/59] Refactor --- aggregate_root/lib/aggregate_root/default_apply_strategy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aggregate_root/lib/aggregate_root/default_apply_strategy.rb b/aggregate_root/lib/aggregate_root/default_apply_strategy.rb index b7149f00ec..ff3ffa147c 100644 --- a/aggregate_root/lib/aggregate_root/default_apply_strategy.rb +++ b/aggregate_root/lib/aggregate_root/default_apply_strategy.rb @@ -24,7 +24,7 @@ def on_handler(aggregate, event_type) def missing_handler(aggregate, event_type) if strict - lambda { |event| raise MissingHandler.new("Missing handler method on aggregate #{aggregate.class} for #{event_type}") } + raise MissingHandler.new("Missing handler method on aggregate #{aggregate.class} for #{event_type}") else NullHandler end From 7df8857ebb3b8f9069120d9d03040f7d8326f542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Sat, 9 Jan 2021 14:45:49 +0100 Subject: [PATCH 29/59] Kill mutants --- aggregate_root/spec/aggregate_root_spec.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/aggregate_root/spec/aggregate_root_spec.rb b/aggregate_root/spec/aggregate_root_spec.rb index 4d288c49c0..7147c0dc0d 100644 --- a/aggregate_root/spec/aggregate_root_spec.rb +++ b/aggregate_root/spec/aggregate_root_spec.rb @@ -26,12 +26,14 @@ def expire private - on Orders::Events::OrderCreated do |_event| - @status = :created + on Orders::Events::OrderCreated do |event| + @status = :created + @created_at = event.valid_at end - on Orders::Events::OrderExpired do |_event| - @status = :expired + on Orders::Events::OrderExpired do |event| + @status = :expired + @expired_at = event.valid_at end end end From 9eab186ac34f9cdbee25bbc5b297f34303a03997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 15 Jan 2021 02:00:17 +0100 Subject: [PATCH 30/59] rails_event_store -> ruby_event_store --- .../lib/ruby_event_store/profiler.rb | 2 +- rails_event_store/spec/client_spec.rb | 4 ++-- .../ruby_event_store/instrumented_dispatcher.rb | 2 +- .../ruby_event_store/instrumented_repository.rb | 14 +++++++------- .../mappers/instrumented_mapper.rb | 4 ++-- .../spec/instrumented_dispatcher_spec.rb | 2 +- .../spec/instrumented_repository_spec.rb | 14 +++++++------- .../spec/mappers/instrumented_mapper_spec.rb | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/contrib/ruby_event_store-profiler/lib/ruby_event_store/profiler.rb b/contrib/ruby_event_store-profiler/lib/ruby_event_store/profiler.rb index 6fdd3314c1..e5efbae937 100644 --- a/contrib/ruby_event_store-profiler/lib/ruby_event_store/profiler.rb +++ b/contrib/ruby_event_store-profiler/lib/ruby_event_store/profiler.rb @@ -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) diff --git a/rails_event_store/spec/client_spec.rb b/rails_event_store/spec/client_spec.rb index c6f1be912f..4e969cdcc6 100644 --- a/rails_event_store/spec/client_spec.rb +++ b/rails_event_store/spec/client_spec.rb @@ -37,7 +37,7 @@ module RailsEventStore client = Client.new(repository: RubyEventStore::InMemoryRepository.new) received_notifications = 0 - ActiveSupport::Notifications.subscribe("append_to_stream.repository.rails_event_store") do + ActiveSupport::Notifications.subscribe("append_to_stream.repository.ruby_event_store") do received_notifications += 1 end @@ -49,7 +49,7 @@ module RailsEventStore specify "wraps mapper into instrumentation" do client = Client.new(repository: RubyEventStore::InMemoryRepository.new, mapper: RubyEventStore::Mappers::Default.new) received_notifications = 0 - ActiveSupport::Notifications.subscribe("serialize.mapper.rails_event_store") { received_notifications += 1 } + ActiveSupport::Notifications.subscribe("serialize.mapper.ruby_event_store") { received_notifications += 1 } client.publish(TestEvent.new) diff --git a/ruby_event_store/lib/ruby_event_store/instrumented_dispatcher.rb b/ruby_event_store/lib/ruby_event_store/instrumented_dispatcher.rb index c1171c7b9d..a9f3c84f7a 100644 --- a/ruby_event_store/lib/ruby_event_store/instrumented_dispatcher.rb +++ b/ruby_event_store/lib/ruby_event_store/instrumented_dispatcher.rb @@ -8,7 +8,7 @@ def initialize(dispatcher, instrumentation) end def call(subscriber, event, record) - instrumentation.instrument("call.dispatcher.rails_event_store", event: event, subscriber: subscriber) do + instrumentation.instrument("call.dispatcher.ruby_event_store", event: event, subscriber: subscriber) do dispatcher.call(subscriber, event, record) end end diff --git a/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb b/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb index a70311818c..384452e7f2 100644 --- a/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb +++ b/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb @@ -8,43 +8,43 @@ def initialize(repository, instrumentation) end def append_to_stream(records, stream, expected_version) - instrumentation.instrument("append_to_stream.repository.rails_event_store", events: records, stream: stream) do + instrumentation.instrument("append_to_stream.repository.ruby_event_store", events: records, stream: stream) do repository.append_to_stream(records, stream, expected_version) end end def link_to_stream(event_ids, stream, expected_version) - instrumentation.instrument("link_to_stream.repository.rails_event_store", event_ids: event_ids, stream: stream) do + instrumentation.instrument("link_to_stream.repository.ruby_event_store", event_ids: event_ids, stream: stream) do repository.link_to_stream(event_ids, stream, expected_version) end end def delete_stream(stream) - instrumentation.instrument("delete_stream.repository.rails_event_store", stream: stream) do + instrumentation.instrument("delete_stream.repository.ruby_event_store", stream: stream) do repository.delete_stream(stream) end end def read(specification) - instrumentation.instrument("read.repository.rails_event_store", specification: specification) do + instrumentation.instrument("read.repository.ruby_event_store", specification: specification) do repository.read(specification) end end def count(specification) - instrumentation.instrument("count.repository.rails_event_store", specification: specification) do + instrumentation.instrument("count.repository.ruby_event_store", specification: specification) do repository.count(specification) end end def update_messages(messages) - instrumentation.instrument("update_messages.repository.rails_event_store", messages: messages) do + instrumentation.instrument("update_messages.repository.ruby_event_store", messages: messages) do repository.update_messages(messages) end end def streams_of(event_id) - instrumentation.instrument("streams_of.repository.rails_event_store", event_id: event_id) do + instrumentation.instrument("streams_of.repository.ruby_event_store", event_id: event_id) do repository.streams_of(event_id) end end diff --git a/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb b/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb index 74afe07369..21ce7e9650 100644 --- a/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb +++ b/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb @@ -9,13 +9,13 @@ def initialize(mapper, instrumentation) end def event_to_record(event) - instrumentation.instrument("serialize.mapper.rails_event_store", domain_event: event) do + instrumentation.instrument("serialize.mapper.ruby_event_store", domain_event: event) do mapper.event_to_record(event) end end def record_to_event(record) - instrumentation.instrument("deserialize.mapper.rails_event_store", record: record) do + instrumentation.instrument("deserialize.mapper.ruby_event_store", record: record) do mapper.record_to_event(record) end end diff --git a/ruby_event_store/spec/instrumented_dispatcher_spec.rb b/ruby_event_store/spec/instrumented_dispatcher_spec.rb index aa1c0a4e47..c54f051e6a 100644 --- a/ruby_event_store/spec/instrumented_dispatcher_spec.rb +++ b/ruby_event_store/spec/instrumented_dispatcher_spec.rb @@ -23,7 +23,7 @@ module RubyEventStore specify "instruments" do instrumented_dispatcher = InstrumentedDispatcher.new(spy, ActiveSupport::Notifications) - subscribe_to("call.dispatcher.rails_event_store") do |notification_calls| + subscribe_to("call.dispatcher.ruby_event_store") do |notification_calls| event = Object.new record = Object.new subscriber = -> { } diff --git a/ruby_event_store/spec/instrumented_repository_spec.rb b/ruby_event_store/spec/instrumented_repository_spec.rb index e793271630..bd583e914b 100644 --- a/ruby_event_store/spec/instrumented_repository_spec.rb +++ b/ruby_event_store/spec/instrumented_repository_spec.rb @@ -21,7 +21,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("append_to_stream.repository.rails_event_store") do |notification_calls| + subscribe_to("append_to_stream.repository.ruby_event_store") do |notification_calls| instrumented_repository.append_to_stream([record], stream, expected_version) expect(notification_calls).to eq([{ events: [record], stream: stream }]) @@ -40,7 +40,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("link_to_stream.repository.rails_event_store") do |notification_calls| + subscribe_to("link_to_stream.repository.ruby_event_store") do |notification_calls| instrumented_repository.link_to_stream([event_id], stream, expected_version) expect(notification_calls).to eq([{ event_ids: [event_id], stream: stream }]) @@ -59,7 +59,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("delete_stream.repository.rails_event_store") do |notification_calls| + subscribe_to("delete_stream.repository.ruby_event_store") do |notification_calls| instrumented_repository.delete_stream("SomeStream") expect(notification_calls).to eq([{ stream: "SomeStream" }]) @@ -99,7 +99,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("read.repository.rails_event_store") do |notification_calls| + subscribe_to("read.repository.ruby_event_store") do |notification_calls| specification = double instrumented_repository.read(specification) @@ -120,7 +120,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("count.repository.rails_event_store") do |notification_calls| + subscribe_to("count.repository.ruby_event_store") do |notification_calls| specification = double instrumented_repository.count(specification) @@ -140,7 +140,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("update_messages.repository.rails_event_store") do |notification_calls| + subscribe_to("update_messages.repository.ruby_event_store") do |notification_calls| instrumented_repository.update_messages([record]) expect(notification_calls).to eq([{ messages: [record] }]) @@ -160,7 +160,7 @@ module RubyEventStore specify "instruments" do instrumented_repository = InstrumentedRepository.new(spy, ActiveSupport::Notifications) - subscribe_to("streams_of.repository.rails_event_store") do |notification_calls| + subscribe_to("streams_of.repository.ruby_event_store") do |notification_calls| uuid = SecureRandom.uuid instrumented_repository.streams_of(uuid) diff --git a/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb b/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb index bcd41dada6..de0e21a096 100644 --- a/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb +++ b/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb @@ -20,7 +20,7 @@ module Mappers specify "instruments" do instrumented_mapper = InstrumentedMapper.new(spy, ActiveSupport::Notifications) - subscribe_to("serialize.mapper.rails_event_store") do |notification_calls| + subscribe_to("serialize.mapper.ruby_event_store") do |notification_calls| instrumented_mapper.event_to_record(event) expect(notification_calls).to eq([{ domain_event: event }]) end @@ -38,7 +38,7 @@ module Mappers specify "instruments" do instrumented_mapper = InstrumentedMapper.new(spy, ActiveSupport::Notifications) - subscribe_to("deserialize.mapper.rails_event_store") do |notification_calls| + subscribe_to("deserialize.mapper.ruby_event_store") do |notification_calls| instrumented_mapper.record_to_event(record) expect(notification_calls).to eq([{ record: record }]) end From 3864da13b42cb8480bc76e070c0a9ae7409b9edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 15 Jan 2021 02:04:48 +0100 Subject: [PATCH 31/59] Rename to match passed arguments --- .../lib/ruby_event_store/instrumented_repository.rb | 8 ++++---- ruby_event_store/spec/instrumented_repository_spec.rb | 8 ++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb b/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb index 384452e7f2..b2133a1794 100644 --- a/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb +++ b/ruby_event_store/lib/ruby_event_store/instrumented_repository.rb @@ -8,7 +8,7 @@ def initialize(repository, instrumentation) end def append_to_stream(records, stream, expected_version) - instrumentation.instrument("append_to_stream.repository.ruby_event_store", events: records, stream: stream) do + instrumentation.instrument("append_to_stream.repository.ruby_event_store", records: records, stream: stream) do repository.append_to_stream(records, stream, expected_version) end end @@ -37,9 +37,9 @@ def count(specification) end end - def update_messages(messages) - instrumentation.instrument("update_messages.repository.ruby_event_store", messages: messages) do - repository.update_messages(messages) + def update_messages(records) + instrumentation.instrument("update_messages.repository.ruby_event_store", records: records) do + repository.update_messages(records) end end diff --git a/ruby_event_store/spec/instrumented_repository_spec.rb b/ruby_event_store/spec/instrumented_repository_spec.rb index bd583e914b..65e50bdb87 100644 --- a/ruby_event_store/spec/instrumented_repository_spec.rb +++ b/ruby_event_store/spec/instrumented_repository_spec.rb @@ -24,7 +24,9 @@ module RubyEventStore subscribe_to("append_to_stream.repository.ruby_event_store") do |notification_calls| instrumented_repository.append_to_stream([record], stream, expected_version) - expect(notification_calls).to eq([{ events: [record], stream: stream }]) + expect(notification_calls).to eq([ + { records: [record], stream: stream } + ]) end end end @@ -143,7 +145,9 @@ module RubyEventStore subscribe_to("update_messages.repository.ruby_event_store") do |notification_calls| instrumented_repository.update_messages([record]) - expect(notification_calls).to eq([{ messages: [record] }]) + expect(notification_calls).to eq([ + { records: [record] } + ]) end end end From 478b0644862937e97c68c257e60e83cec09659fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 15 Jan 2021 02:12:35 +0100 Subject: [PATCH 32/59] Rename to match instrumented methods and their arguments --- rails_event_store/spec/client_spec.rb | 2 +- .../lib/ruby_event_store/mappers/instrumented_mapper.rb | 4 ++-- ruby_event_store/spec/mappers/instrumented_mapper_spec.rb | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rails_event_store/spec/client_spec.rb b/rails_event_store/spec/client_spec.rb index 4e969cdcc6..127280fa83 100644 --- a/rails_event_store/spec/client_spec.rb +++ b/rails_event_store/spec/client_spec.rb @@ -49,7 +49,7 @@ module RailsEventStore specify "wraps mapper into instrumentation" do client = Client.new(repository: RubyEventStore::InMemoryRepository.new, mapper: RubyEventStore::Mappers::Default.new) received_notifications = 0 - ActiveSupport::Notifications.subscribe("serialize.mapper.ruby_event_store") { received_notifications += 1 } + ActiveSupport::Notifications.subscribe("event_to_record.mapper.ruby_event_store") { received_notifications += 1 } client.publish(TestEvent.new) diff --git a/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb b/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb index 21ce7e9650..3e5f42dc8f 100644 --- a/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb +++ b/ruby_event_store/lib/ruby_event_store/mappers/instrumented_mapper.rb @@ -9,13 +9,13 @@ def initialize(mapper, instrumentation) end def event_to_record(event) - instrumentation.instrument("serialize.mapper.ruby_event_store", domain_event: event) do + instrumentation.instrument("event_to_record.mapper.ruby_event_store", event: event) do mapper.event_to_record(event) end end def record_to_event(record) - instrumentation.instrument("deserialize.mapper.ruby_event_store", record: record) do + instrumentation.instrument("record_to_event.mapper.ruby_event_store", record: record) do mapper.record_to_event(record) end end diff --git a/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb b/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb index de0e21a096..6f91908d67 100644 --- a/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb +++ b/ruby_event_store/spec/mappers/instrumented_mapper_spec.rb @@ -20,9 +20,9 @@ module Mappers specify "instruments" do instrumented_mapper = InstrumentedMapper.new(spy, ActiveSupport::Notifications) - subscribe_to("serialize.mapper.ruby_event_store") do |notification_calls| + subscribe_to("event_to_record.mapper.ruby_event_store") do |notification_calls| instrumented_mapper.event_to_record(event) - expect(notification_calls).to eq([{ domain_event: event }]) + expect(notification_calls).to eq([{ event: event }]) end end end @@ -38,7 +38,7 @@ module Mappers specify "instruments" do instrumented_mapper = InstrumentedMapper.new(spy, ActiveSupport::Notifications) - subscribe_to("deserialize.mapper.ruby_event_store") do |notification_calls| + subscribe_to("record_to_event.mapper.ruby_event_store") do |notification_calls| instrumented_mapper.record_to_event(record) expect(notification_calls).to eq([{ record: record }]) end From 2cddc9e9f778f3e11ff7b64ecd9bf6bd5ade9918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miros=C5=82aw=20Prag=C5=82owski?= Date: Sun, 27 Nov 2022 19:56:57 +0100 Subject: [PATCH 33/59] Projections redesigned Projection class is redesigned here. It now only suports read & reduce based on existing events, without possibility to subscribe for events. New & redesigned: * replace `from_all_streams` & `from_stream` with passing read scopes to `call` method, it allows to fully use all read specification features to define what events should be handled * instead of providing several streams (and starting points) to be processed `call` expects several read scopes * `when` method replaced with `on` method, with usage consistent with `on` handlers (as in `AggregateRoot`), the `on` methods require block to process state & event and it must return new projection state * allows to use simple values as initial state, no need to use hash to pass values, `nil` is the initial default state now * initial state is passed to projection using costructor Typical usage: ```ruby account_balance = RailsEventStore::Projection .new(0.0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(client.read) ``` --- .../lib/ruby_event_store/projection.rb | 89 ++------ ruby_event_store/spec/projection_spec.rb | 215 +++++++----------- 2 files changed, 97 insertions(+), 207 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/projection.rb b/ruby_event_store/lib/ruby_event_store/projection.rb index d06a1a62a0..ecd6a979f7 100644 --- a/ruby_event_store/lib/ruby_event_store/projection.rb +++ b/ruby_event_store/lib/ruby_event_store/projection.rb @@ -2,94 +2,45 @@ module RubyEventStore class Projection - private_class_method :new + ANONYMOUS_CLASS = "# { {} } + @init = -> { initial_state } end - attr_reader :streams, :handlers - - def init(handler) - @init = handler - self - end + def on(*event_klasses, &block) + raise(ArgumentError, 'No handler block given') unless block_given? - def when(events, handler) - Array(events).each { |event| handlers[event.to_s] = handler } + event_klasses.each do |event_klass| + name = event_klass.to_s + raise(ArgumentError, 'Anonymous class is missing name') if name.start_with? ANONYMOUS_CLASS + @handlers[name] = ->(state, event) { block.call(state, event) } + end self end - def initial_state - @init.call - end - - def current_state - @current_state ||= initial_state - end - - def call(event) - handlers.fetch(event.event_type).(current_state, event) - end - - def handled_events - handlers.keys - end - - def run(event_store, start: nil, count: PAGE_SIZE) + def call(*scopes) return initial_state if handled_events.empty? - streams.any? ? reduce_from_streams(event_store, start, count) : reduce_from_all_streams(event_store, start, count) - end - - private - def valid_starting_point?(start) - return true unless start - streams.any? ? (start.instance_of?(Array) && start.size === streams.size) : start.instance_of?(String) + scopes.reduce(initial_state) do |state, scope| + scope.of_types(handled_events).reduce(state, &method(:transition)) + end end - def reduce_from_streams(event_store, start, count) - raise ArgumentError.new("Start must be an array with event ids") unless valid_starting_point?(start) - streams - .zip(start_events(start)) - .reduce(initial_state) do |state, (stream_name, start_event_id)| - read_scope(event_store, stream_name, count, start_event_id).reduce(state, &method(:transition)) - end - end - - def reduce_from_all_streams(event_store, start, count) - raise ArgumentError.new("Start must be valid event id") unless valid_starting_point?(start) - read_scope(event_store, nil, count, start).reduce(initial_state, &method(:transition)) - end + private - def read_scope(event_store, stream, count, start) - scope = event_store.read.in_batches(count) - scope = scope.of_type(handled_events) - scope = scope.stream(stream) if stream - scope = scope.from(start) if start - scope + def initial_state + @init.call end - def start_events(start) - start ? start : Array.new + def handled_events + @handlers.keys end def transition(state, event) - handlers.fetch(event.event_type).call(state, event) - state + @handlers.fetch(event.event_type).call(state, event) end end end diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index a1ec514431..982db29e7a 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -25,12 +25,11 @@ module RubyEventStore account_balance = Projection - .from_stream(stream_name) - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store) - expect(account_balance).to eq(total: 25) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read) + expect(account_balance).to eq(25) end specify "reduce events from many streams" do @@ -40,27 +39,11 @@ module RubyEventStore account_balance = Projection - .from_stream(%w[Customer$1 Customer$3]) - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store) - expect(account_balance).to eq(total: 5) - end - - specify "raises proper errors when wrong argument were passed (stream mode)" do - projection = - Projection - .from_stream(%w[Customer$1 Customer$2]) - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) - expect { projection.run(event_store, start: :last) }.to raise_error ArgumentError, - "Start must be an array with event ids" - expect { projection.run(event_store, start: 0.7) }.to raise_error ArgumentError, - "Start must be an array with event ids" - expect { projection.run(event_store, start: [SecureRandom.uuid]) }.to raise_error ArgumentError, - "Start must be an array with event ids" + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read.stream("Customer$1"), event_store.read.stream("Customer$3")) + expect(account_balance).to eq(5) end specify "take events from all streams" do @@ -71,28 +54,15 @@ module RubyEventStore account_balance = Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read) - expect(account_balance.run(event_store)).to eq(total: 1) + expect(account_balance).to eq(1) end - specify "raises proper errors when wrong argument were pass (all streams mode)" do - projection = - Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) - expect { projection.run(event_store, start: :last) }.to raise_error ArgumentError, "Start must be valid event id" - expect { projection.run(event_store, start: 0.7) }.to raise_error ArgumentError, "Start must be valid event id" - expect { projection.run(event_store, start: [SecureRandom.uuid]) }.to raise_error ArgumentError, - "Start must be valid event id" - end - - specify "empty hash is default inital state" do + specify "state could be more complex than simple value" do event_store.append( [ MoneyDeposited.new(data: { amount: 10 }), @@ -103,11 +73,10 @@ module RubyEventStore ) stats = - Projection - .from_stream(stream_name) - .when(MoneyDeposited, ->(state, event) { state[:last_deposit] = event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:last_withdrawal] = event.data[:amount] }) - .run(event_store) + Projection.new({}) + .on(MoneyDeposited) { |state, event| state[:last_deposit] = event.data[:amount]; state } + .on(MoneyWithdrawn) { |state, event| state[:last_withdrawal] = event.data[:amount]; state } + .call(event_store.read.stream(stream_name)) expect(stats).to eq(last_deposit: 20, last_withdrawal: 5) end @@ -119,11 +88,10 @@ module RubyEventStore deposits = Projection - .from_stream(stream_name) - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .run(event_store) - expect(deposits).to eq(total: 10) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .call(event_store.read.stream(stream_name)) + expect(deposits).to eq(10) end specify "subsrcibe one handler to many events" do @@ -134,35 +102,10 @@ module RubyEventStore cashflow = Projection - .from_stream(stream_name) - .init(-> { { total: 0 } }) - .when([MoneyDeposited, MoneyWithdrawn], ->(state, event) { state[:total] += event.data[:amount] }) - .run(event_store) - expect(cashflow).to eq(total: 12) - end - - specify "subscribe to events" do - deposits = - Projection - .from_stream(stream_name) - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - event_store.subscribe(deposits, to: deposits.handled_events) - event_store.publish( - [MoneyDeposited.new(data: { amount: 10 }), MoneyDeposited.new(data: { amount: 5 })], - stream_name: stream_name - ) - - expect(deposits.current_state).to eq(total: 15) - end - - specify "using default constructor" do - expect { Projection.new(stream_name) }.to raise_error(NoMethodError, /private method `new'/) - end - - specify "at least one stream must be given" do - expect { Projection.from_stream([]) }.to raise_error(ArgumentError, "At least one stream must be given") - expect { Projection.from_stream(nil) }.to raise_error(ArgumentError, "At least one stream must be given") + .new(0) + .on(MoneyDeposited, MoneyWithdrawn) { |state, event| state += event.data[:amount] } + .call(event_store.read.stream(stream_name)) + expect(cashflow).to eq(12) end specify "all events from the stream must be read (starting from begining of the stream)" do @@ -179,12 +122,11 @@ module RubyEventStore balance = Projection - .from_stream(stream_name) - .init(-> { { total: 0 } }) - .when([MoneyDeposited], ->(state, event) { state[:total] += event.data[:amount] }) - .when([MoneyWithdrawn], ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, count: 2) - expect(balance).to eq(total: 14) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read.stream(stream_name).in_batches(2)) + expect(balance).to eq(14) end specify "all events from the stream must be read (starting from given event)" do @@ -201,12 +143,11 @@ module RubyEventStore balance = Projection - .from_stream(stream_name) - .init(-> { { total: 0 } }) - .when([MoneyDeposited], ->(state, event) { state[:total] += event.data[:amount] }) - .when([MoneyWithdrawn], ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, start: [starting.event_id], count: 2) - expect(balance).to eq(total: 6) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read.stream(stream_name).from(starting.event_id).in_batches(2)) + expect(balance).to eq(6) end specify "all events from all streams must be read (starting from begining of each stream)" do @@ -218,12 +159,11 @@ module RubyEventStore balance = Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when([MoneyDeposited], ->(state, event) { state[:total] += event.data[:amount] }) - .when([MoneyWithdrawn], ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, count: 2) - expect(balance).to eq(total: 14) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read.in_batches(2)) + expect(balance).to eq(14) end specify "all events from all streams must be read (starting from given event)" do @@ -235,12 +175,11 @@ module RubyEventStore balance = Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when([MoneyDeposited], ->(state, event) { state[:total] += event.data[:amount] }) - .when([MoneyWithdrawn], ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, start: starting.event_id, count: 2) - expect(balance).to eq(total: 6) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(event_store.read.from(starting.event_id).in_batches(2)) + expect(balance).to eq(6) end specify "only events that have handlers must be read" do @@ -260,54 +199,54 @@ module RubyEventStore balance = Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when([MoneyDeposited], ->(state, event) { state[:total] += event.data[:amount] }) - .when([MoneyWithdrawn, MoneyLost], ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, count: 100) - expect(balance).to eq(total: 6) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn, MoneyLost) { |state, event| state -= event.data[:amount] } + .call(event_store.read.in_batches(100)) + expect(balance).to eq(6) end specify do specification = Specification.new(SpecificationReader.new(repository, mapper)) - expected = specification.in_batches(2).of_type([MoneyDeposited, MoneyWithdrawn]).result - expect(repository).to receive(:read).with(expected).and_return([]) + scope = specification.in_batches(2).of_type([MoneyDeposited, MoneyWithdrawn]) + expect(repository).to receive(:read).with(scope.result).and_return([]) Projection - .from_all_streams - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, count: 2) + .new(0) + .on(MoneyDeposited) { |state, event| state += event.data[:amount] } + .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } + .call(scope) end - specify do - specification = Specification.new(SpecificationReader.new(repository, mapper)) - expected = specification.in_batches(2).of_type([MoneyDeposited, MoneyWithdrawn]).stream("FancyStream").result - expect(repository).to receive(:read).with(expected).and_return([]) + specify "default initial state" do + expect(Projection.new.call([])).to eq(nil) + end - Projection - .from_stream("FancyStream") - .init(-> { { total: 0 } }) - .when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] }) - .when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] }) - .run(event_store, count: 2) + specify "block must be given to on event handlers" do + expect do + Projection.new.on(MoneyDeposited) + end.to raise_error(ArgumentError, "No handler block given") + end + + it "does not support anonymous events" do + expect do + Projection.new.on(Class.new) { |_state, _event| } + end.to raise_error(ArgumentError, "Anonymous class is missing name") end specify do expect(repository).not_to receive(:read) - - state = Projection.from_all_streams.init(-> { { total: 0 } }).run(event_store, count: 2) - - expect(state).to eq({ total: 0 }) + state = Projection.new.call(event_store.read) + expect(state).to eq(nil) end specify do expect(repository).not_to receive(:read) - state = Projection.from_all_streams.run(event_store) + initial_state = Object.new + state = Projection.new(initial_state).call(event_store.read) - expect(state).to eq({}) + expect(state).to eq(initial_state) end end end From e2040f3929220182992b0c203a3420ce65efd463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Mon, 6 Feb 2023 15:25:27 +0100 Subject: [PATCH 34/59] Recreate EventClassRemapper in contrib/transformations --- .../lib/ruby_event_store/transformations.rb | 1 + .../transformations/event_class_remapper.rb | 30 ++++++++++++++ .../spec/event_class_remapper_spec.rb | 39 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations/event_class_remapper.rb create mode 100644 contrib/ruby_event_store-transformations/spec/event_class_remapper_spec.rb diff --git a/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations.rb b/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations.rb index 4ebb692552..a335959bde 100644 --- a/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations.rb +++ b/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations.rb @@ -3,6 +3,7 @@ require_relative "transformations/version" require_relative "transformations/with_indifferent_access" require_relative "transformations/identity_map" +require_relative "transformations/event_class_remapper" module RubyEventStore module Transformations diff --git a/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations/event_class_remapper.rb b/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations/event_class_remapper.rb new file mode 100644 index 0000000000..63082d2451 --- /dev/null +++ b/contrib/ruby_event_store-transformations/lib/ruby_event_store/transformations/event_class_remapper.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module RubyEventStore + module Transformations + class EventClassRemapper + def initialize(class_map) + @class_map = class_map + end + + def dump(record) + record + end + + def load(record) + Record.new( + event_id: record.event_id, + event_type: class_map[record.event_type] || record.event_type, + data: record.data, + metadata: record.metadata, + timestamp: record.timestamp, + valid_at: record.valid_at + ) + end + + private + + attr_reader :class_map + end + end +end diff --git a/contrib/ruby_event_store-transformations/spec/event_class_remapper_spec.rb b/contrib/ruby_event_store-transformations/spec/event_class_remapper_spec.rb new file mode 100644 index 0000000000..24cfbea921 --- /dev/null +++ b/contrib/ruby_event_store-transformations/spec/event_class_remapper_spec.rb @@ -0,0 +1,39 @@ +require "spec_helper" + +module RubyEventStore + module Transformations + ::RSpec.describe EventClassRemapper do + let(:time) { Time.now.utc } + let(:uuid) { SecureRandom.uuid } + + def record(event_type: "TestEvent") + Record.new( + event_id: uuid, + metadata: { + some: "meta" + }, + data: { + some: "value" + }, + event_type: event_type, + timestamp: time, + valid_at: time + ) + end + + let(:changeable_record) { record(event_type: "EventNameBeforeRefactor") } + let(:changed_record) { record(event_type: "SomethingHappened") } + let(:class_map) { { "EventNameBeforeRefactor" => "SomethingHappened" } } + + specify "#dump" do + expect(EventClassRemapper.new(class_map).dump(record)).to eq(record) + expect(EventClassRemapper.new(class_map).dump(record)).to eq(record) + end + + specify "#load" do + expect(EventClassRemapper.new(class_map).load(record)).to eq(record) + expect(EventClassRemapper.new(class_map).load(changeable_record)).to eq(changed_record) + end + end + end +end From f13b20abda176d116649efe7c1e5b475d7854545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Mon, 6 Feb 2023 13:53:56 +0100 Subject: [PATCH 35/59] Allow projection from one stream only --- .../lib/ruby_event_store/projection.rb | 6 ++---- ruby_event_store/spec/projection_spec.rb | 14 -------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/projection.rb b/ruby_event_store/lib/ruby_event_store/projection.rb index ecd6a979f7..ece0462c4e 100644 --- a/ruby_event_store/lib/ruby_event_store/projection.rb +++ b/ruby_event_store/lib/ruby_event_store/projection.rb @@ -21,12 +21,10 @@ def on(*event_klasses, &block) self end - def call(*scopes) + def call(scope) return initial_state if handled_events.empty? - scopes.reduce(initial_state) do |state, scope| - scope.of_types(handled_events).reduce(state, &method(:transition)) - end + scope.of_types(handled_events).reduce(initial_state, &method(:transition)) end private diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index 982db29e7a..0e394855e8 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -32,20 +32,6 @@ module RubyEventStore expect(account_balance).to eq(25) end - specify "reduce events from many streams" do - event_store.append(MoneyDeposited.new(data: { amount: 10 }), stream_name: "Customer$1") - event_store.append(MoneyDeposited.new(data: { amount: 20 }), stream_name: "Customer$2") - event_store.append(MoneyWithdrawn.new(data: { amount: 5 }), stream_name: "Customer$3") - - account_balance = - Projection - .new(0) - .on(MoneyDeposited) { |state, event| state += event.data[:amount] } - .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } - .call(event_store.read.stream("Customer$1"), event_store.read.stream("Customer$3")) - expect(account_balance).to eq(5) - end - specify "take events from all streams" do event_store.append(MoneyDeposited.new(data: { amount: 1 }), stream_name: "Customer$1") event_store.append(MoneyDeposited.new(data: { amount: 1 }), stream_name: "Customer$2") From 2b4ce59d447d8e84aa8ad9f2e543294fda5f303d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Mon, 6 Feb 2023 14:02:09 +0100 Subject: [PATCH 36/59] Factory method instead of constructor --- .../lib/ruby_event_store/projection.rb | 6 ++++ ruby_event_store/spec/projection_spec.rb | 32 +++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/projection.rb b/ruby_event_store/lib/ruby_event_store/projection.rb index ece0462c4e..031f63a1fb 100644 --- a/ruby_event_store/lib/ruby_event_store/projection.rb +++ b/ruby_event_store/lib/ruby_event_store/projection.rb @@ -2,6 +2,8 @@ module RubyEventStore class Projection + private_class_method :new + ANONYMOUS_CLASS = "# { initial_state } end + def self.init(initial_state = nil) + new(initial_state) + end + def on(*event_klasses, &block) raise(ArgumentError, 'No handler block given') unless block_given? diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index 0e394855e8..a589ed5dff 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -25,7 +25,7 @@ module RubyEventStore account_balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(event_store.read) @@ -40,7 +40,7 @@ module RubyEventStore account_balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(event_store.read) @@ -59,7 +59,7 @@ module RubyEventStore ) stats = - Projection.new({}) + Projection.init({}) .on(MoneyDeposited) { |state, event| state[:last_deposit] = event.data[:amount]; state } .on(MoneyWithdrawn) { |state, event| state[:last_withdrawal] = event.data[:amount]; state } .call(event_store.read.stream(stream_name)) @@ -74,7 +74,7 @@ module RubyEventStore deposits = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .call(event_store.read.stream(stream_name)) expect(deposits).to eq(10) @@ -88,7 +88,7 @@ module RubyEventStore cashflow = Projection - .new(0) + .init(0) .on(MoneyDeposited, MoneyWithdrawn) { |state, event| state += event.data[:amount] } .call(event_store.read.stream(stream_name)) expect(cashflow).to eq(12) @@ -108,7 +108,7 @@ module RubyEventStore balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(event_store.read.stream(stream_name).in_batches(2)) @@ -129,7 +129,7 @@ module RubyEventStore balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(event_store.read.stream(stream_name).from(starting.event_id).in_batches(2)) @@ -145,7 +145,7 @@ module RubyEventStore balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(event_store.read.in_batches(2)) @@ -161,7 +161,7 @@ module RubyEventStore balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(event_store.read.from(starting.event_id).in_batches(2)) @@ -185,7 +185,7 @@ module RubyEventStore balance = Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn, MoneyLost) { |state, event| state -= event.data[:amount] } .call(event_store.read.in_batches(100)) @@ -198,31 +198,31 @@ module RubyEventStore expect(repository).to receive(:read).with(scope.result).and_return([]) Projection - .new(0) + .init(0) .on(MoneyDeposited) { |state, event| state += event.data[:amount] } .on(MoneyWithdrawn) { |state, event| state -= event.data[:amount] } .call(scope) end specify "default initial state" do - expect(Projection.new.call([])).to eq(nil) + expect(Projection.init.call([])).to eq(nil) end specify "block must be given to on event handlers" do expect do - Projection.new.on(MoneyDeposited) + Projection.init.on(MoneyDeposited) end.to raise_error(ArgumentError, "No handler block given") end it "does not support anonymous events" do expect do - Projection.new.on(Class.new) { |_state, _event| } + Projection.init.on(Class.new) { |_state, _event| } end.to raise_error(ArgumentError, "Anonymous class is missing name") end specify do expect(repository).not_to receive(:read) - state = Projection.new.call(event_store.read) + state = Projection.init.call(event_store.read) expect(state).to eq(nil) end @@ -230,7 +230,7 @@ module RubyEventStore expect(repository).not_to receive(:read) initial_state = Object.new - state = Projection.new(initial_state).call(event_store.read) + state = Projection.init(initial_state).call(event_store.read) expect(state).to eq(initial_state) end From abd21103889169a8dd50daa2e996f87d98fc100c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 8 Feb 2023 15:13:35 +0100 Subject: [PATCH 37/59] Always include OnDSL in DefaultApplyStrategy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DefaultApplyStrategy relies on OnDSL. Therefore they always have to go together. https: //github.com/RailsEventStore/rails_event_store/issues/982 Co-authored-by: Paweł Pacana Co-authored-by: Szymon Fiedler --- aggregate_root/lib/aggregate_root.rb | 10 ++++++++-- aggregate_root/spec/aggregate_root_spec.rb | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index c8d3157f54..5bb070e2f1 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -76,10 +76,16 @@ def marshal_load(vars) end end - def self.with_default_apply_strategy + def self.with_default_apply_strategy(strict: true) Module.new do def self.included(host_class) - host_class.include AggregateRoot.with_strategy(-> { DefaultApplyStrategy.new }) + host_class.extend OnDSL + host_class.extend Constructor + host_class.include AggregateMethods + end + + define_method :apply_strategy do + DefaultApplyStrategy.new(strict: strict) end end end diff --git a/aggregate_root/spec/aggregate_root_spec.rb b/aggregate_root/spec/aggregate_root_spec.rb index 7147c0dc0d..b6caf0091b 100644 --- a/aggregate_root/spec/aggregate_root_spec.rb +++ b/aggregate_root/spec/aggregate_root_spec.rb @@ -68,7 +68,7 @@ def expire 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_apply_strategy(strict: false) } order = klass.new spanish_inquisition = Orders::Events::SpanishInquisition.new expect { order.apply(spanish_inquisition) }.to_not raise_error From c08316fb962be5498b2e6be7d5bae29879f43e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 8 Feb 2023 15:16:29 +0100 Subject: [PATCH 38/59] Rename WithDefaultApplyStrategy -> WithDefaultStrategy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Szymon Fiedler Co-authored-by: Paweł Pacana --- aggregate_root/lib/aggregate_root.rb | 4 ++-- aggregate_root/spec/aggregate_root_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index 5bb070e2f1..68a9a2be14 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -76,7 +76,7 @@ def marshal_load(vars) end end - def self.with_default_apply_strategy(strict: true) + def self.with_default_strategy(strict: true) Module.new do def self.included(host_class) host_class.extend OnDSL @@ -105,6 +105,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 diff --git a/aggregate_root/spec/aggregate_root_spec.rb b/aggregate_root/spec/aggregate_root_spec.rb index b6caf0091b..eaed8056fe 100644 --- a/aggregate_root/spec/aggregate_root_spec.rb +++ b/aggregate_root/spec/aggregate_root_spec.rb @@ -68,7 +68,7 @@ def expire it "should ignore missing apply method based on a default non-strict apply strategy" do klass = - Class.new { include AggregateRoot.with_default_apply_strategy(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 @@ -111,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. From b35e97f393c3e52ef47fd47cfa6f01562ceb724a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 8 Feb 2023 15:19:58 +0100 Subject: [PATCH 39/59] Custom strategy shouldn't rely on OnDSL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paweł Pacana Co-authored-by: Szymon Fiedler --- aggregate_root/lib/aggregate_root.rb | 1 - ruby_event_store-rspec/spec/spec_helper.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index 68a9a2be14..f4bc3273f1 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -93,7 +93,6 @@ def self.included(host_class) def self.with_strategy(strategy) Module.new do def self.included(host_class) - host_class.extend OnDSL host_class.extend Constructor host_class.include AggregateMethods end diff --git a/ruby_event_store-rspec/spec/spec_helper.rb b/ruby_event_store-rspec/spec/spec_helper.rb index 8dd5035a34..258c5014d2 100644 --- a/ruby_event_store-rspec/spec/spec_helper.rb +++ b/ruby_event_store-rspec/spec/spec_helper.rb @@ -9,7 +9,7 @@ BazEvent = Class.new(RubyEventStore::Event) class TestAggregate - include AggregateRoot.with_strategy(-> { AggregateRoot::DefaultApplyStrategy.new(strict: false) }) + include AggregateRoot.with_default_strategy(strict: false) def foo apply(FooEvent.new) From 1a5261ff6c4ef164743440723e2fef926dfeae6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 8 Feb 2023 12:41:53 +0100 Subject: [PATCH 40/59] Make DeafultApplyStrategy private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paweł Pacana Co-authored-by: Szymon Fiedler --- aggregate_root/lib/aggregate_root/default_apply_strategy.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/aggregate_root/lib/aggregate_root/default_apply_strategy.rb b/aggregate_root/lib/aggregate_root/default_apply_strategy.rb index ff3ffa147c..0249894d05 100644 --- a/aggregate_root/lib/aggregate_root/default_apply_strategy.rb +++ b/aggregate_root/lib/aggregate_root/default_apply_strategy.rb @@ -32,4 +32,5 @@ def missing_handler(aggregate, event_type) attr_reader :strict, :on_methods end + private_constant :DefaultApplyStrategy end From 1afa38083716cedc4ccd717206ccb4e76fd3c59e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Tue, 7 Feb 2023 18:47:56 +0100 Subject: [PATCH 41/59] Simplify dispatcher All we need is subscriber responding to `call` method. Therefore, passing class is not allowed anymore. It either has to be class instance or something that evaluates to class instance. --- ruby_event_store/lib/ruby_event_store/dispatcher.rb | 9 +-------- ruby_event_store/spec/dispatcher_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/dispatcher.rb b/ruby_event_store/lib/ruby_event_store/dispatcher.rb index a1d3fda68c..6736e379ba 100644 --- a/ruby_event_store/lib/ruby_event_store/dispatcher.rb +++ b/ruby_event_store/lib/ruby_event_store/dispatcher.rb @@ -3,18 +3,11 @@ module RubyEventStore class Dispatcher def call(subscriber, event, _) - subscriber = subscriber.new if Class === subscriber subscriber.call(event) end def verify(subscriber) - begin - subscriber_instance = Class === subscriber ? subscriber.new : subscriber - rescue ArgumentError - false - else - subscriber_instance.respond_to?(:call) - end + subscriber.respond_to?(:call) end end end diff --git a/ruby_event_store/spec/dispatcher_spec.rb b/ruby_event_store/spec/dispatcher_spec.rb index a3bee9aaab..3b0c966112 100644 --- a/ruby_event_store/spec/dispatcher_spec.rb +++ b/ruby_event_store/spec/dispatcher_spec.rb @@ -38,11 +38,11 @@ def call; end specify "calls subscribed class" do expect(HandlerClass).to receive(:new).and_return(handler) expect(handler).to receive(:call).with(event) - Dispatcher.new.call(HandlerClass, event, record) + Dispatcher.new.call(-> (event) { HandlerClass.new.call(event) }, event, record) end specify "allows callable classes and instances" do - expect(Dispatcher.new.verify(HandlerClass)).to eq(true) + expect(Dispatcher.new.verify(-> { HandlerClass.new })).to eq(true) expect(Dispatcher.new.verify(HandlerClass.new)).to eq(true) expect(Dispatcher.new.verify(Proc.new { "yo" })).to eq(true) end From 756e02184c2a2027cb0293ea305afaa9bf7bc7bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Tue, 7 Feb 2023 19:08:26 +0100 Subject: [PATCH 42/59] Rename ImmediateAsyncDispatcher to ImmediateDispatcher The dispatcher doesn't indicate that the message will be handled asynchronously. It indicates that the event will be dispatched immediately. No matter if it's handled sync or async --- contrib/ruby_event_store-outbox/README.md | 2 +- .../spec/protobuf_integration_spec.rb | 2 +- .../spec/async_handler_helpers_spec.rb | 2 +- ..._async_dispatcher.rb => after_commit_dispatcher.rb} | 0 ...patcher_spec.rb => after_commit_dispatcher_spec.rb} | 0 rails_event_store/spec/async_handler_helpers_spec.rb | 2 +- ruby_event_store/lib/ruby_event_store.rb | 2 +- ...ate_async_dispatcher.rb => immediate_dispatcher.rb} | 2 +- ruby_event_store/spec/client_spec.rb | 4 ++-- ...dispatcher_spec.rb => immediate_dispatcher_spec.rb} | 10 +++++----- 10 files changed, 13 insertions(+), 13 deletions(-) rename rails_event_store/lib/rails_event_store/{after_commit_async_dispatcher.rb => after_commit_dispatcher.rb} (100%) rename rails_event_store/spec/{after_commit_async_dispatcher_spec.rb => after_commit_dispatcher_spec.rb} (100%) rename ruby_event_store/lib/ruby_event_store/{immediate_async_dispatcher.rb => immediate_dispatcher.rb} (89%) rename ruby_event_store/spec/{immediate_async_dispatcher_spec.rb => immediate_dispatcher_spec.rb} (73%) diff --git a/contrib/ruby_event_store-outbox/README.md b/contrib/ruby_event_store-outbox/README.md index 49a1488472..60c9c8777e 100644 --- a/contrib/ruby_event_store-outbox/README.md +++ b/contrib/ruby_event_store-outbox/README.md @@ -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), ... ) ``` diff --git a/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb b/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb index e06ab8c743..4121d3d03d 100644 --- a/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb +++ b/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb @@ -27,7 +27,7 @@ module RubyEventStore mapper: Protobuf::Mappers::Protobuf.new, dispatcher: ComposedDispatcher.new( - ImmediateAsyncDispatcher.new(scheduler: RailsEventStore::ActiveJobScheduler.new(serializer: NULL)), + ImmediateDispatcher.new(scheduler: RailsEventStore::ActiveJobScheduler.new(serializer: NULL)), Dispatcher.new ) ) diff --git a/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb b/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb index 325bd41842..ff2fb1cfd6 100644 --- a/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb +++ b/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb @@ -13,7 +13,7 @@ def perform(event) let(:event_store) do RubyEventStore::Client.new( dispatcher: - ImmediateAsyncDispatcher.new( + ImmediateDispatcher.new( scheduler: SidekiqScheduler.new(serializer: serializer) ) ) diff --git a/rails_event_store/lib/rails_event_store/after_commit_async_dispatcher.rb b/rails_event_store/lib/rails_event_store/after_commit_dispatcher.rb similarity index 100% rename from rails_event_store/lib/rails_event_store/after_commit_async_dispatcher.rb rename to rails_event_store/lib/rails_event_store/after_commit_dispatcher.rb diff --git a/rails_event_store/spec/after_commit_async_dispatcher_spec.rb b/rails_event_store/spec/after_commit_dispatcher_spec.rb similarity index 100% rename from rails_event_store/spec/after_commit_async_dispatcher_spec.rb rename to rails_event_store/spec/after_commit_dispatcher_spec.rb diff --git a/rails_event_store/spec/async_handler_helpers_spec.rb b/rails_event_store/spec/async_handler_helpers_spec.rb index 86d79f4c75..8f1229c246 100644 --- a/rails_event_store/spec/async_handler_helpers_spec.rb +++ b/rails_event_store/spec/async_handler_helpers_spec.rb @@ -71,7 +71,7 @@ def perform(event) let(:another_event_store) { RailsEventStore::Client.new } let(:json_event_store) do RailsEventStore::Client.new( - dispatcher: RubyEventStore::ImmediateAsyncDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: JSON)) + dispatcher: RubyEventStore::ImmediateDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: JSON)) ) end let(:application) { instance_double(Rails::Application) } diff --git a/ruby_event_store/lib/ruby_event_store.rb b/ruby_event_store/lib/ruby_event_store.rb index 8b3690640b..aa2293059a 100644 --- a/ruby_event_store/lib/ruby_event_store.rb +++ b/ruby_event_store/lib/ruby_event_store.rb @@ -37,7 +37,7 @@ require_relative "ruby_event_store/batch_enumerator" require_relative "ruby_event_store/correlated_commands" require_relative "ruby_event_store/link_by_metadata" -require_relative "ruby_event_store/immediate_async_dispatcher" +require_relative "ruby_event_store/immediate_dispatcher" require_relative "ruby_event_store/composed_dispatcher" require_relative "ruby_event_store/version" require_relative "ruby_event_store/instrumented_repository" diff --git a/ruby_event_store/lib/ruby_event_store/immediate_async_dispatcher.rb b/ruby_event_store/lib/ruby_event_store/immediate_dispatcher.rb similarity index 89% rename from ruby_event_store/lib/ruby_event_store/immediate_async_dispatcher.rb rename to ruby_event_store/lib/ruby_event_store/immediate_dispatcher.rb index e9f908ceb3..5f9b2fa855 100644 --- a/ruby_event_store/lib/ruby_event_store/immediate_async_dispatcher.rb +++ b/ruby_event_store/lib/ruby_event_store/immediate_dispatcher.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RubyEventStore - class ImmediateAsyncDispatcher + class ImmediateDispatcher def initialize(scheduler:) @scheduler = scheduler end diff --git a/ruby_event_store/spec/client_spec.rb b/ruby_event_store/spec/client_spec.rb index aab457ef5b..b05592901b 100644 --- a/ruby_event_store/spec/client_spec.rb +++ b/ruby_event_store/spec/client_spec.rb @@ -926,7 +926,7 @@ def self.event_type Client.new( repository: InMemoryRepository.new(serializer: serializer), dispatcher: - ImmediateAsyncDispatcher.new( + ImmediateDispatcher.new( scheduler: ScheduledWithSerialization.new(serializer: serializer) ) ) @@ -948,7 +948,7 @@ def self.event_type Client.new( repository: InMemoryRepository.new(serializer: serializer_1), dispatcher: - ImmediateAsyncDispatcher.new( + ImmediateDispatcher.new( scheduler: ScheduledWithSerialization.new(serializer: serializer_2) ) ) diff --git a/ruby_event_store/spec/immediate_async_dispatcher_spec.rb b/ruby_event_store/spec/immediate_dispatcher_spec.rb similarity index 73% rename from ruby_event_store/spec/immediate_async_dispatcher_spec.rb rename to ruby_event_store/spec/immediate_dispatcher_spec.rb index c9fc5e93fc..9cfef0563d 100644 --- a/ruby_event_store/spec/immediate_async_dispatcher_spec.rb +++ b/ruby_event_store/spec/immediate_dispatcher_spec.rb @@ -3,7 +3,7 @@ require "ruby_event_store/spec/scheduler_lint" module RubyEventStore - ::RSpec.describe ImmediateAsyncDispatcher do + ::RSpec.describe ImmediateDispatcher do class MyCustomScheduler def call(klass, record) klass.perform_async(record) @@ -14,7 +14,7 @@ def verify(klass) end end - it_behaves_like :dispatcher, ImmediateAsyncDispatcher.new(scheduler: MyCustomScheduler.new) + it_behaves_like :dispatcher, ImmediateDispatcher.new(scheduler: MyCustomScheduler.new) it_behaves_like :scheduler, MyCustomScheduler.new let(:event) { instance_double(Event) } @@ -23,7 +23,7 @@ def verify(klass) describe "#call" do specify do - dispatcher = ImmediateAsyncDispatcher.new(scheduler: scheduler) + dispatcher = ImmediateDispatcher.new(scheduler: scheduler) handler = spy dispatcher.call(handler, event, record) @@ -34,14 +34,14 @@ def verify(klass) describe "#verify" do specify do - dispatcher = ImmediateAsyncDispatcher.new(scheduler: scheduler) + dispatcher = ImmediateDispatcher.new(scheduler: scheduler) handler = double(perform_async: true) expect(dispatcher.verify(handler)).to eq(true) end specify do - dispatcher = ImmediateAsyncDispatcher.new(scheduler: scheduler) + dispatcher = ImmediateDispatcher.new(scheduler: scheduler) handler = double expect(dispatcher.verify(handler)).to eq(false) From 935e4d03d8cb37fd10eff5de24cb4db7bd8729f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Tue, 7 Feb 2023 19:09:57 +0100 Subject: [PATCH 43/59] Rename AfterCommitAsyncDispatcher to AfterCommitDispatcher Basically same reason as ImmediateAsyncDispatcher -> ImmediateDispatcher --- contrib/ruby_event_store-sidekiq_scheduler/README.md | 4 ++-- .../lib/rails_event_store/after_commit_dispatcher.rb | 2 +- rails_event_store/lib/rails_event_store/all.rb | 2 +- rails_event_store/lib/rails_event_store/client.rb | 2 +- rails_event_store/lib/rails_event_store/json_client.rb | 2 +- rails_event_store/spec/after_commit_dispatcher_spec.rb | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contrib/ruby_event_store-sidekiq_scheduler/README.md b/contrib/ruby_event_store-sidekiq_scheduler/README.md index 63350ff595..4812224a4d 100644 --- a/contrib/ruby_event_store-sidekiq_scheduler/README.md +++ b/contrib/ruby_event_store-sidekiq_scheduler/README.md @@ -16,8 +16,8 @@ Declare the scheduler in your Ruby Event Store configuration. We recommend to us ```ruby event_store = RailsEventStore::Client.new( - dispatcher: RailsEventStore::AfterCommitAsyncDispatcher.new(scheduler: RubyEventStore::SidekiqScheduler.new(serializer: RubyEventStore::Serializers::YAML), -) + dispatcher: RailsEventStore::AfterCommitDispatcher.new(scheduler: RubyEventStore::SidekiqScheduler.new(serializer: RubyEventStore::Serializers::YAML), + ) ``` Read more about [using asynchronous handlers](https://railseventstore.org/docs/v2/subscribe/#async-handlers) diff --git a/rails_event_store/lib/rails_event_store/after_commit_dispatcher.rb b/rails_event_store/lib/rails_event_store/after_commit_dispatcher.rb index 38633a2bf1..837c8b1cbf 100644 --- a/rails_event_store/lib/rails_event_store/after_commit_dispatcher.rb +++ b/rails_event_store/lib/rails_event_store/after_commit_dispatcher.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RailsEventStore - class AfterCommitAsyncDispatcher + class AfterCommitDispatcher def initialize(scheduler:) @scheduler = scheduler end diff --git a/rails_event_store/lib/rails_event_store/all.rb b/rails_event_store/lib/rails_event_store/all.rb index 0df18d71d5..be80be2653 100644 --- a/rails_event_store/lib/rails_event_store/all.rb +++ b/rails_event_store/lib/rails_event_store/all.rb @@ -3,7 +3,7 @@ require "ruby_event_store" require_relative "async_handler_helpers" require_relative "link_by_metadata" -require_relative "after_commit_async_dispatcher" +require_relative "after_commit_dispatcher" require_relative "active_job_scheduler" require_relative 'active_job_id_only_scheduler' require_relative "client" diff --git a/rails_event_store/lib/rails_event_store/client.rb b/rails_event_store/lib/rails_event_store/client.rb index ed2f2734b6..acdd5cd424 100644 --- a/rails_event_store/lib/rails_event_store/client.rb +++ b/rails_event_store/lib/rails_event_store/client.rb @@ -9,7 +9,7 @@ def initialize( repository: RubyEventStore::ActiveRecord::EventRepository.new(serializer: RubyEventStore::Serializers::YAML), subscriptions: RubyEventStore::Subscriptions.new, dispatcher: RubyEventStore::ComposedDispatcher.new( - RailsEventStore::AfterCommitAsyncDispatcher.new( + RailsEventStore::AfterCommitDispatcher.new( scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML) ), RubyEventStore::Dispatcher.new diff --git a/rails_event_store/lib/rails_event_store/json_client.rb b/rails_event_store/lib/rails_event_store/json_client.rb index d1f5108403..85872f78b6 100644 --- a/rails_event_store/lib/rails_event_store/json_client.rb +++ b/rails_event_store/lib/rails_event_store/json_client.rb @@ -30,7 +30,7 @@ def initialize( repository: RubyEventStore::ActiveRecord::EventRepository.new(serializer: RubyEventStore::NULL), subscriptions: RubyEventStore::Subscriptions.new, dispatcher: RubyEventStore::ComposedDispatcher.new( - RailsEventStore::AfterCommitAsyncDispatcher.new( + RailsEventStore::AfterCommitDispatcher.new( scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML) ), RubyEventStore::Dispatcher.new diff --git a/rails_event_store/spec/after_commit_dispatcher_spec.rb b/rails_event_store/spec/after_commit_dispatcher_spec.rb index 59e799e574..4e9c6ca3ac 100644 --- a/rails_event_store/spec/after_commit_dispatcher_spec.rb +++ b/rails_event_store/spec/after_commit_dispatcher_spec.rb @@ -2,7 +2,7 @@ require "ruby_event_store/spec/dispatcher_lint" module RailsEventStore - ::RSpec.describe AfterCommitAsyncDispatcher do + ::RSpec.describe AfterCommitDispatcher do DummyError = Class.new(StandardError) class DummyRecord < ActiveRecord::Base @@ -10,13 +10,13 @@ class DummyRecord < ActiveRecord::Base after_commit -> { raise DummyError } end - it_behaves_like :dispatcher, AfterCommitAsyncDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML)) + it_behaves_like :dispatcher, AfterCommitDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML)) let(:event) { TimeEnrichment.with(RubyEventStore::Event.new(event_id: "83c3187f-84f6-4da7-8206-73af5aca7cc8")) } let(:record) { RubyEventStore::Mappers::Default.new.event_to_record(event) } let(:serialized_record) { record.serialize(RubyEventStore::Serializers::YAML).to_h.transform_keys(&:to_s) } - let(:dispatcher) { AfterCommitAsyncDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML)) } + let(:dispatcher) { AfterCommitDispatcher.new(scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML)) } before(:each) { MyActiveJobAsyncHandler.reset } From c8bc3dae1c7fa96ba3d72185c852d02ac9af7df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 8 Feb 2023 15:42:02 +0100 Subject: [PATCH 44/59] Rename Dispatcher to SyncScheduler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paweł Pacana Co-authored-by: Szymon Fiedler --- contrib/ruby_event_store-profiler/README.md | 2 +- .../ruby_event_store-profiler/examples/demo | 2 +- .../spec/profiler_spec.rb | 2 +- .../spec/protobuf_integration_spec.rb | 2 +- .../lib/rails_event_store/client.rb | 2 +- .../lib/rails_event_store/json_client.rb | 2 +- ruby_event_store/lib/ruby_event_store.rb | 2 +- .../lib/ruby_event_store/client.rb | 2 +- .../lib/ruby_event_store/spec/broker_lint.rb | 4 ++-- .../{dispatcher.rb => sync_scheduler.rb} | 2 +- .../spec/instrumented_dispatcher_spec.rb | 4 ++-- ...patcher_spec.rb => sync_scheduler_spec.rb} | 22 +++++++++---------- 12 files changed, 24 insertions(+), 24 deletions(-) rename ruby_event_store/lib/ruby_event_store/{dispatcher.rb => sync_scheduler.rb} (90%) rename ruby_event_store/spec/{dispatcher_spec.rb => sync_scheduler_spec.rb} (62%) diff --git a/contrib/ruby_event_store-profiler/README.md b/contrib/ruby_event_store-profiler/README.md index 19d5988b67..d3de56b190 100644 --- a/contrib/ruby_event_store-profiler/README.md +++ b/contrib/ruby_event_store-profiler/README.md @@ -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) diff --git a/contrib/ruby_event_store-profiler/examples/demo b/contrib/ruby_event_store-profiler/examples/demo index bf6cb97f30..57d14d0653 100755 --- a/contrib/ruby_event_store-profiler/examples/demo +++ b/contrib/ruby_event_store-profiler/examples/demo @@ -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 diff --git a/contrib/ruby_event_store-profiler/spec/profiler_spec.rb b/contrib/ruby_event_store-profiler/spec/profiler_spec.rb index bdaeb6efa0..eae3402750 100644 --- a/contrib/ruby_event_store-profiler/spec/profiler_spec.rb +++ b/contrib/ruby_event_store-profiler/spec/profiler_spec.rb @@ -7,7 +7,7 @@ module RubyEventStore Client.new( repository: InstrumentedRepository.new(InMemoryRepository.new, instrumenter), mapper: Mappers::InstrumentedMapper.new(Mappers::Default.new, instrumenter), - dispatcher: InstrumentedDispatcher.new(Dispatcher.new, instrumenter) + dispatcher: InstrumentedDispatcher.new(SyncScheduler.new, instrumenter) ) end diff --git a/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb b/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb index 4121d3d03d..0bb04c2068 100644 --- a/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb +++ b/contrib/ruby_event_store-protobuf/spec/protobuf_integration_spec.rb @@ -28,7 +28,7 @@ module RubyEventStore dispatcher: ComposedDispatcher.new( ImmediateDispatcher.new(scheduler: RailsEventStore::ActiveJobScheduler.new(serializer: NULL)), - Dispatcher.new + SyncScheduler.new ) ) client.subscribe(->(ev) { @ev = ev }, to: [ResTesting::OrderCreated.descriptor.name]) diff --git a/rails_event_store/lib/rails_event_store/client.rb b/rails_event_store/lib/rails_event_store/client.rb index acdd5cd424..efcc338612 100644 --- a/rails_event_store/lib/rails_event_store/client.rb +++ b/rails_event_store/lib/rails_event_store/client.rb @@ -12,7 +12,7 @@ def initialize( RailsEventStore::AfterCommitDispatcher.new( scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML) ), - RubyEventStore::Dispatcher.new + RubyEventStore::SyncScheduler.new ), clock: default_clock, correlation_id_generator: default_correlation_id_generator, diff --git a/rails_event_store/lib/rails_event_store/json_client.rb b/rails_event_store/lib/rails_event_store/json_client.rb index 85872f78b6..fd520de743 100644 --- a/rails_event_store/lib/rails_event_store/json_client.rb +++ b/rails_event_store/lib/rails_event_store/json_client.rb @@ -33,7 +33,7 @@ def initialize( RailsEventStore::AfterCommitDispatcher.new( scheduler: ActiveJobScheduler.new(serializer: RubyEventStore::Serializers::YAML) ), - RubyEventStore::Dispatcher.new + RubyEventStore::SyncScheduler.new ), clock: default_clock, correlation_id_generator: default_correlation_id_generator, diff --git a/ruby_event_store/lib/ruby_event_store.rb b/ruby_event_store/lib/ruby_event_store.rb index aa2293059a..7b0a5f3fa0 100644 --- a/ruby_event_store/lib/ruby_event_store.rb +++ b/ruby_event_store/lib/ruby_event_store.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "ruby_event_store/dispatcher" +require_relative "ruby_event_store/sync_scheduler" require_relative "ruby_event_store/subscriptions" require_relative "ruby_event_store/broker" require_relative "ruby_event_store/in_memory_repository" diff --git a/ruby_event_store/lib/ruby_event_store/client.rb b/ruby_event_store/lib/ruby_event_store/client.rb index 354c3ea7cc..e0444099e3 100644 --- a/ruby_event_store/lib/ruby_event_store/client.rb +++ b/ruby_event_store/lib/ruby_event_store/client.rb @@ -8,7 +8,7 @@ def initialize( repository: InMemoryRepository.new, mapper: Mappers::Default.new, subscriptions: Subscriptions.new, - dispatcher: Dispatcher.new, + dispatcher: SyncScheduler.new, clock: default_clock, correlation_id_generator: default_correlation_id_generator, event_type_resolver: EventTypeResolver.new diff --git a/ruby_event_store/lib/ruby_event_store/spec/broker_lint.rb b/ruby_event_store/lib/ruby_event_store/spec/broker_lint.rb index 07f6538c21..0c338d68e9 100644 --- a/ruby_event_store/lib/ruby_event_store/spec/broker_lint.rb +++ b/ruby_event_store/lib/ruby_event_store/spec/broker_lint.rb @@ -3,7 +3,7 @@ let(:record) { instance_double(::RubyEventStore::Record) } let(:handler) { HandlerClass.new } let(:subscriptions) { ::RubyEventStore::Subscriptions.new } - let(:dispatcher) { ::RubyEventStore::Dispatcher.new } + let(:dispatcher) { ::RubyEventStore::SyncScheduler.new } let(:broker) { broker_klass.new(subscriptions: subscriptions, dispatcher: dispatcher) } specify "no dispatch when no subscriptions" do @@ -48,7 +48,7 @@ allow(dispatcher).to receive(:verify).and_return(false) expect { broker.add_subscription(HandlerClass, []) }.to raise_error( RubyEventStore::InvalidHandler, - /Handler HandlerClass is invalid for dispatcher .*Dispatcher/ + /Handler HandlerClass is invalid for dispatcher .*SyncScheduler/ ) expect { broker.add_global_subscription(HandlerClass) }.to raise_error( RubyEventStore::InvalidHandler, diff --git a/ruby_event_store/lib/ruby_event_store/dispatcher.rb b/ruby_event_store/lib/ruby_event_store/sync_scheduler.rb similarity index 90% rename from ruby_event_store/lib/ruby_event_store/dispatcher.rb rename to ruby_event_store/lib/ruby_event_store/sync_scheduler.rb index 6736e379ba..d9cf2b75b6 100644 --- a/ruby_event_store/lib/ruby_event_store/dispatcher.rb +++ b/ruby_event_store/lib/ruby_event_store/sync_scheduler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RubyEventStore - class Dispatcher + class SyncScheduler def call(subscriber, event, _) subscriber.call(event) end diff --git a/ruby_event_store/spec/instrumented_dispatcher_spec.rb b/ruby_event_store/spec/instrumented_dispatcher_spec.rb index c54f051e6a..b56060d27d 100644 --- a/ruby_event_store/spec/instrumented_dispatcher_spec.rb +++ b/ruby_event_store/spec/instrumented_dispatcher_spec.rb @@ -6,7 +6,7 @@ module RubyEventStore ::RSpec.describe InstrumentedDispatcher do - it_behaves_like :dispatcher, InstrumentedDispatcher.new(Dispatcher.new, ActiveSupport::Notifications) + it_behaves_like :dispatcher, InstrumentedDispatcher.new(SyncScheduler.new, ActiveSupport::Notifications) describe "#call" do specify "wraps around original implementation" do @@ -60,7 +60,7 @@ module RubyEventStore end specify "method unknown by instrumentation and unknown by dispatcher" do - some_dispatcher = Dispatcher.new + some_dispatcher = SyncScheduler.new instrumented_dispatcher = InstrumentedDispatcher.new(some_dispatcher, ActiveSupport::Notifications) expect(instrumented_dispatcher).not_to respond_to(:arbitrary_method_name) diff --git a/ruby_event_store/spec/dispatcher_spec.rb b/ruby_event_store/spec/sync_scheduler_spec.rb similarity index 62% rename from ruby_event_store/spec/dispatcher_spec.rb rename to ruby_event_store/spec/sync_scheduler_spec.rb index 3b0c966112..1996e0cd19 100644 --- a/ruby_event_store/spec/dispatcher_spec.rb +++ b/ruby_event_store/spec/sync_scheduler_spec.rb @@ -2,20 +2,20 @@ require "ruby_event_store/spec/dispatcher_lint" module RubyEventStore - ::RSpec.describe Dispatcher do - it_behaves_like :dispatcher, Dispatcher.new + ::RSpec.describe SyncScheduler do + it_behaves_like :dispatcher, SyncScheduler.new let(:event) { instance_double(Event) } let(:record) { instance_double(Record) } let(:handler) { HandlerClass.new } specify "does not allow silly subscribers" do - expect(Dispatcher.new.verify(:symbol)).to eq(false) - expect(Dispatcher.new.verify(Object.new)).to eq(false) + expect(SyncScheduler.new.verify(:symbol)).to eq(false) + expect(SyncScheduler.new.verify(Object.new)).to eq(false) end specify "does not allow class without instance method #call" do klass = Class.new - expect(Dispatcher.new.verify(klass)).to eq(false) + expect(SyncScheduler.new.verify(klass)).to eq(false) end specify "does not allow class without constructor requiring arguments" do @@ -27,24 +27,24 @@ def initialize(something) def call; end end - expect(Dispatcher.new.verify(klass)).to eq(false) + expect(SyncScheduler.new.verify(klass)).to eq(false) end specify "calls subscribed instance" do expect(handler).to receive(:call).with(event) - Dispatcher.new.call(handler, event, record) + SyncScheduler.new.call(handler, event, record) end specify "calls subscribed class" do expect(HandlerClass).to receive(:new).and_return(handler) expect(handler).to receive(:call).with(event) - Dispatcher.new.call(-> (event) { HandlerClass.new.call(event) }, event, record) + SyncScheduler.new.call(-> (event) { HandlerClass.new.call(event) }, event, record) end specify "allows callable classes and instances" do - expect(Dispatcher.new.verify(-> { HandlerClass.new })).to eq(true) - expect(Dispatcher.new.verify(HandlerClass.new)).to eq(true) - expect(Dispatcher.new.verify(Proc.new { "yo" })).to eq(true) + expect(SyncScheduler.new.verify(-> { HandlerClass.new })).to eq(true) + expect(SyncScheduler.new.verify(HandlerClass.new)).to eq(true) + expect(SyncScheduler.new.verify(Proc.new { "yo" })).to eq(true) end private From d496844682dbf321a56abb21a4a024bf232ebf1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 8 Feb 2023 16:20:32 +0100 Subject: [PATCH 45/59] Prefer lazy event store initialization ref: eb7381887f01733944f48ba4ae66b45c47e60187 --- .../lib/rails_event_store/async_handler_helpers.rb | 8 +++----- rails_event_store/spec/async_handler_helpers_spec.rb | 5 ++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/rails_event_store/lib/rails_event_store/async_handler_helpers.rb b/rails_event_store/lib/rails_event_store/async_handler_helpers.rb index a0b1393b4d..b64d2cba71 100644 --- a/rails_event_store/lib/rails_event_store/async_handler_helpers.rb +++ b/rails_event_store/lib/rails_event_store/async_handler_helpers.rb @@ -7,14 +7,12 @@ def self.with_defaults end def self.with( - event_store: Rails.configuration.event_store, - event_store_locator: nil, - serializer: RubyEventStore::Serializers::YAML + serializer: RubyEventStore::Serializers::YAML, + event_store_locator: -> { Rails.configuration.event_store } ) Module.new do define_method :perform do |payload| - event_store = event_store_locator.call if event_store_locator - super(event_store.deserialize(serializer: serializer, **payload.transform_keys(&:to_sym))) + super(event_store_locator.call.deserialize(serializer: serializer, **payload.transform_keys(&:to_sym))) end end end diff --git a/rails_event_store/spec/async_handler_helpers_spec.rb b/rails_event_store/spec/async_handler_helpers_spec.rb index 8f1229c246..c3b70f259d 100644 --- a/rails_event_store/spec/async_handler_helpers_spec.rb +++ b/rails_event_store/spec/async_handler_helpers_spec.rb @@ -95,7 +95,7 @@ def perform(event) end specify "with specified event store" do - HandlerWithAnotherEventStore.prepend RailsEventStore::AsyncHandler.with(event_store: another_event_store) + HandlerWithAnotherEventStore.prepend RailsEventStore::AsyncHandler.with(event_store_locator: -> { another_event_store} ) event_store.subscribe_to_all_events(HandlerWithAnotherEventStore) event_store.publish(ev = RubyEventStore::Event.new) expect($queue.pop).to eq(ev) @@ -103,7 +103,6 @@ def perform(event) specify "with specified event store locator" do HandlerWithEventStoreLocator.prepend RailsEventStore::AsyncHandler.with( - event_store: nil, event_store_locator: -> { another_event_store } ) another_event_store.subscribe_to_all_events(HandlerWithEventStoreLocator) @@ -113,7 +112,7 @@ def perform(event) specify "with specified serializer" do HandlerWithSpecifiedSerializer.prepend RailsEventStore::AsyncHandler.with( - event_store: json_event_store, + event_store_locator: -> { json_event_store }, serializer: JSON ) json_event_store.subscribe_to_all_events(HandlerWithSpecifiedSerializer) From 67565f96eae44a44ece4f798766a9b3f6fcd640f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Fri, 10 Feb 2023 17:05:33 +0100 Subject: [PATCH 46/59] Namespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paweł Pacana --- rails_event_store/spec/active_job_id_only_scheduler_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rails_event_store/spec/active_job_id_only_scheduler_spec.rb b/rails_event_store/spec/active_job_id_only_scheduler_spec.rb index 9b605aa218..c4d6791513 100644 --- a/rails_event_store/spec/active_job_id_only_scheduler_spec.rb +++ b/rails_event_store/spec/active_job_id_only_scheduler_spec.rb @@ -24,7 +24,7 @@ module RailsEventStore it_behaves_like :scheduler, ActiveJobIdOnlyScheduler.new - let(:event) { TimeEnrichment.with(Event.new(event_id: "83c3187f-84f6-4da7-8206-73af5aca7cc8"), timestamp: Time.utc(2019, 9, 30)) } + let(:event) { TimeEnrichment.with(RubyEventStore::Event.new(event_id: "83c3187f-84f6-4da7-8206-73af5aca7cc8"), timestamp: Time.utc(2019, 9, 30)) } let(:record) { RubyEventStore::Mappers::Default.new.event_to_record(event) } describe "#verify" do From 783195866a2df3bdadd4f1ff0f234cc035d2b50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Fri, 10 Feb 2023 17:13:34 +0100 Subject: [PATCH 47/59] Remove ANONYMOUS_CLASS guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not a practical example. Hard to imagine real life use case for passing anonymous class. Co-authored-by: Paweł Pacana --- aggregate_root/lib/aggregate_root.rb | 3 --- aggregate_root/spec/aggregate_root_spec.rb | 10 ---------- ruby_event_store/lib/ruby_event_store/projection.rb | 3 --- 3 files changed, 16 deletions(-) diff --git a/aggregate_root/lib/aggregate_root.rb b/aggregate_root/lib/aggregate_root.rb index f4bc3273f1..c945f8cc14 100644 --- a/aggregate_root/lib/aggregate_root.rb +++ b/aggregate_root/lib/aggregate_root.rb @@ -9,12 +9,9 @@ module AggregateRoot module OnDSL - ANONYMOUS_CLASS = "# { initial_state } @@ -20,7 +18,6 @@ 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 @handlers[name] = ->(state, event) { block.call(state, event) } end From 570e07413233515d349ba547d02365025c0497ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Fri, 10 Feb 2023 17:33:57 +0100 Subject: [PATCH 48/59] Remove anonymous class test from projection_spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paweł Pacana --- ruby_event_store/spec/projection_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index a589ed5dff..ecd0bb093f 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -214,12 +214,6 @@ module RubyEventStore end.to raise_error(ArgumentError, "No handler block given") end - it "does not support anonymous events" do - expect do - Projection.init.on(Class.new) { |_state, _event| } - end.to raise_error(ArgumentError, "Anonymous class is missing name") - end - specify do expect(repository).not_to receive(:read) state = Projection.init.call(event_store.read) From 8f33187b2b8b2e833f8b0a6f1631a601539027ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Mon, 13 Feb 2023 14:50:17 +0100 Subject: [PATCH 49/59] Using projection with event type defined by event's class During an attempt to introduce event_type_resolver into projection I wrote following test. The idea is that you can use two different versions of event with class level method defining the event type. In that case, and in usage presented as in test, the event_type_resolver doesn't bring any value to the projection class. So for now I removed it. Perhaps it does make more sense if we're thinking of other way of using projections? --- ruby_event_store/spec/projection_spec.rb | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index ecd0bb093f..ca35702d1a 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -228,5 +228,33 @@ module RubyEventStore expect(state).to eq(initial_state) end + + specify "events with event type defined as class method" do + class Snowflake < Event + def self.event_type + "snowflake" + end + end + + class SnowflakeV2 < Event + def self.event_type + "snowflake" + end + end + + event_store.append(Snowflake.new(data: { arms: 13 }), stream_name: "snowflake$1") + event_store.append(SnowflakeV2.new(data: { arms: 11 }), stream_name: "snowflake$1") + + state = + Projection + .init({ snowflake: 0 }) + .on(Snowflake, SnowflakeV2) do |state, event| + state[event.class.event_type.to_sym] += event.data.fetch(:arms) + state + end + .call(event_store.read.stream("snowflake$1")) + + expect(state).to eq({ snowflake: 24 }) + end end end From 1060cacf839c4804321c1b46d338210e219d0217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 12 Apr 2023 09:10:05 +0200 Subject: [PATCH 50/59] Add event resolver to projection https://github.com/RailsEventStore/rails_event_store/commit/5cd0154fce7d5fefbf84796eb259356346753a5e#r100429552 --- .../lib/ruby_event_store/projection.rb | 9 +++---- ruby_event_store/spec/projection_spec.rb | 24 +++++++++++++++---- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/ruby_event_store/lib/ruby_event_store/projection.rb b/ruby_event_store/lib/ruby_event_store/projection.rb index be240228c6..85f0b1d06a 100644 --- a/ruby_event_store/lib/ruby_event_store/projection.rb +++ b/ruby_event_store/lib/ruby_event_store/projection.rb @@ -4,20 +4,21 @@ module RubyEventStore class Projection private_class_method :new - def initialize(initial_state = nil) + def initialize(initial_state = nil, event_type_resolver) @handlers = {} + @event_type_resolver = event_type_resolver @init = -> { initial_state } end - def self.init(initial_state = nil) - new(initial_state) + def self.init(initial_state = nil, event_type_resolver: EventTypeResolver.new) + new(initial_state, event_type_resolver) end def on(*event_klasses, &block) raise(ArgumentError, 'No handler block given') unless block_given? event_klasses.each do |event_klass| - name = event_klass.to_s + name = @event_type_resolver.call(event_klass) @handlers[name] = ->(state, event) { block.call(state, event) } end diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index ca35702d1a..97491bddf2 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -229,15 +229,29 @@ module RubyEventStore expect(state).to eq(initial_state) end - specify "events with event type defined as class method" do + specify "events with custom event type" do + class CustomResolver + def call(event) + event.resolves_as + end + end + class Snowflake < Event - def self.event_type + def self.resolves_as + "snowflake" + end + + def event_type "snowflake" end end class SnowflakeV2 < Event - def self.event_type + def self.resolves_as + "snowflake" + end + + def event_type "snowflake" end end @@ -247,9 +261,9 @@ def self.event_type state = Projection - .init({ snowflake: 0 }) + .init({ snowflake: 0 }, event_type_resolver: CustomResolver.new) .on(Snowflake, SnowflakeV2) do |state, event| - state[event.class.event_type.to_sym] += event.data.fetch(:arms) + state[:snowflake] += event.data.fetch(:arms) state end .call(event_store.read.stream("snowflake$1")) From e7e542ba1e2d76eef8c4d4c40bc0751d6ab9023a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 12 Apr 2023 10:36:16 +0200 Subject: [PATCH 51/59] kill mutant --- ruby_event_store/lib/ruby_event_store/projection.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby_event_store/lib/ruby_event_store/projection.rb b/ruby_event_store/lib/ruby_event_store/projection.rb index 85f0b1d06a..755872b157 100644 --- a/ruby_event_store/lib/ruby_event_store/projection.rb +++ b/ruby_event_store/lib/ruby_event_store/projection.rb @@ -4,7 +4,7 @@ module RubyEventStore class Projection private_class_method :new - def initialize(initial_state = nil, event_type_resolver) + def initialize(initial_state, event_type_resolver) @handlers = {} @event_type_resolver = event_type_resolver @init = -> { initial_state } From 76a8cc244fe97cfc4672189e2724b786b08533e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 12 Apr 2023 10:41:33 +0200 Subject: [PATCH 52/59] Kill mutant Rely on the new default instead of explicitly setting it --- ruby_event_store/spec/in_memory_repository_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ruby_event_store/spec/in_memory_repository_spec.rb b/ruby_event_store/spec/in_memory_repository_spec.rb index 8786a7dc46..57a0adfd76 100644 --- a/ruby_event_store/spec/in_memory_repository_spec.rb +++ b/ruby_event_store/spec/in_memory_repository_spec.rb @@ -56,7 +56,7 @@ module RubyEventStore end it "publishing with any position to stream with specific position raise an error" do - repository = InMemoryRepository.new(ensure_supported_any_usage: true) + repository = InMemoryRepository.new repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.auto) expect do @@ -65,7 +65,7 @@ module RubyEventStore end it "publishing with any position to stream with any position does not raise an error" do - repository = InMemoryRepository.new(ensure_supported_any_usage: true) + repository = InMemoryRepository.new repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.any) expect do @@ -74,7 +74,7 @@ module RubyEventStore end it "publishing with specific position to stream with any position raise an error" do - repository = InMemoryRepository.new(ensure_supported_any_usage: true) + repository = InMemoryRepository.new repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.any) expect do @@ -83,7 +83,7 @@ module RubyEventStore end it "linking with any position to stream with specific position raise an error" do - repository = InMemoryRepository.new(ensure_supported_any_usage: true) + repository = InMemoryRepository.new repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.auto) repository.append_to_stream([event1 = SRecord.new], Stream.new("other"), ExpectedVersion.auto) @@ -93,7 +93,7 @@ module RubyEventStore end it "linking with any position to stream with any position does not raise an error" do - repository = InMemoryRepository.new(ensure_supported_any_usage: true) + repository = InMemoryRepository.new repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.any) repository.append_to_stream([event1 = SRecord.new], Stream.new("other"), ExpectedVersion.auto) @@ -103,7 +103,7 @@ module RubyEventStore end it "linking with specific position to stream with any position raise an error" do - repository = InMemoryRepository.new(ensure_supported_any_usage: true) + repository = InMemoryRepository.new repository.append_to_stream([event0 = SRecord.new], Stream.new("stream"), ExpectedVersion.any) repository.append_to_stream([event1 = SRecord.new], Stream.new("other"), ExpectedVersion.auto) From 4a0c022b595b99ec592e08aac20e482199fdc91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Reszke?= Date: Wed, 12 Apr 2023 11:53:13 +0200 Subject: [PATCH 53/59] Change test init for 2.7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reason is the "Why we’re deprecating the automatic conversion" section in the article below https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/ --- ruby_event_store/spec/projection_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby_event_store/spec/projection_spec.rb b/ruby_event_store/spec/projection_spec.rb index 97491bddf2..a12cc0cabb 100644 --- a/ruby_event_store/spec/projection_spec.rb +++ b/ruby_event_store/spec/projection_spec.rb @@ -59,7 +59,7 @@ module RubyEventStore ) stats = - Projection.init({}) + Projection.init({}, **{}) .on(MoneyDeposited) { |state, event| state[:last_deposit] = event.data[:amount]; state } .on(MoneyWithdrawn) { |state, event| state[:last_withdrawal] = event.data[:amount]; state } .call(event_store.read.stream(stream_name)) From c0c44a598551a434272db75c7a2c9e27e8c63c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 29 Sep 2023 13:31:57 +0200 Subject: [PATCH 54/59] Follow instrumentation event renames Co-authored-by: Szymon Fiedler --- contrib/ruby_event_store-profiler/spec/profiler_spec.rb | 4 ++-- contrib/ruby_event_store-protobuf/Gemfile.lock | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contrib/ruby_event_store-profiler/spec/profiler_spec.rb b/contrib/ruby_event_store-profiler/spec/profiler_spec.rb index eae3402750..26a328a27e 100644 --- a/contrib/ruby_event_store-profiler/spec/profiler_spec.rb +++ b/contrib/ruby_event_store-profiler/spec/profiler_spec.rb @@ -37,7 +37,7 @@ def now expect { Profiler.new(instrumenter).measure(&operation) }.to output(<<~EOS).to_stdout metric ms % ───────────────────────────────── - serialize 1000.00 16.67 + event_to_record 1000.00 16.67 append_to_stream 1000.00 16.67 total 6000.00 100.00 @@ -56,7 +56,7 @@ def now $stdout = STDOUT end - expect(return_value).to eq({ "total" => 6000, "serialize" => 1000.0, "append_to_stream" => 1000.0 }) + expect(return_value).to eq({ "total" => 6000, "event_to_record" => 1000.0, "append_to_stream" => 1000.0 }) end end end diff --git a/contrib/ruby_event_store-protobuf/Gemfile.lock b/contrib/ruby_event_store-protobuf/Gemfile.lock index a552e2cb8c..c0dd3c703d 100644 --- a/contrib/ruby_event_store-protobuf/Gemfile.lock +++ b/contrib/ruby_event_store-protobuf/Gemfile.lock @@ -239,7 +239,6 @@ DEPENDENCIES protobuf_nested_struct rails (~> 7.0.7) rails_event_store! - rails_event_store_active_record! rake (>= 10.0) rspec (~> 3.6) ruby_event_store! From f5988d87025e0b390bc052d1e8fd923152e55c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 29 Sep 2023 13:48:56 +0200 Subject: [PATCH 55/59] EventClassRemapper vibes Co-authored-by: Szymon Fiedler --- .../protobuf/mappers/protobuf.rb | 3 +-- .../spec/mappers/protobuf_spec.rb | 23 ------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/contrib/ruby_event_store-protobuf/lib/ruby_event_store/protobuf/mappers/protobuf.rb b/contrib/ruby_event_store-protobuf/lib/ruby_event_store/protobuf/mappers/protobuf.rb index 7b1ba95705..2c6083b9f0 100644 --- a/contrib/ruby_event_store-protobuf/lib/ruby_event_store/protobuf/mappers/protobuf.rb +++ b/contrib/ruby_event_store-protobuf/lib/ruby_event_store/protobuf/mappers/protobuf.rb @@ -10,11 +10,10 @@ def event_type module Mappers class Protobuf < RubyEventStore::Mappers::PipelineMapper - def initialize(events_class_remapping: {}) + def initialize super( RubyEventStore::Mappers::Pipeline.new( Transformation::ProtobufEncoder.new, - RubyEventStore::Mappers::Transformation::EventClassRemapper.new(events_class_remapping), Transformation::ProtobufNestedStructMetadata.new, to_domain_event: Transformation::ProtoEvent.new ) diff --git a/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb b/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb index a1499ee8d6..c55af46a1a 100644 --- a/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb +++ b/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb @@ -203,29 +203,6 @@ module Mappers expect(event.metadata[:timestamp]).to eq(time) expect(event.metadata[:valid_at]).to eq(time) end - - specify "#record_to_event is using events class remapping" do - subject = - RubyEventStore::Protobuf::Mappers::Protobuf.new( - events_class_remapping: { - "res_testing.OrderCreatedBeforeRefactor" => "res_testing.OrderCreated" - } - ) - record = - Record.new( - event_id: "f90b8848-e478-47fe-9b4a-9f2a1d53622b", - data: "", - metadata: "", - event_type: "res_testing.OrderCreatedBeforeRefactor", - timestamp: time, - valid_at: time - ) - event = subject.record_to_event(record) - expect(event.data.class).to eq(ResTesting::OrderCreated) - expect(event.event_type).to eq("res_testing.OrderCreated") - expect(event.metadata[:timestamp]).to eq(time) - expect(event.metadata[:valid_at]).to eq(time) - end end end end From d52040b43b838f2c9ec0bfe59689632bd977deaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 29 Sep 2023 13:53:32 +0200 Subject: [PATCH 56/59] AggregateRoot unserscore handlers vibe Co-authored-by: Szymon Fiedler --- contrib/ruby_event_store-protobuf/spec/aggregate_root_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/ruby_event_store-protobuf/spec/aggregate_root_spec.rb b/contrib/ruby_event_store-protobuf/spec/aggregate_root_spec.rb index 20d08499e8..c75f51f866 100644 --- a/contrib/ruby_event_store-protobuf/spec/aggregate_root_spec.rb +++ b/contrib/ruby_event_store-protobuf/spec/aggregate_root_spec.rb @@ -34,7 +34,7 @@ def initialize(uuid) private - def apply_order_created(*) + on "res_testing.OrderCreated" do |_event| @status = :created end @@ -78,7 +78,7 @@ def apply_order_created(*) expect { order.apply(spanish_inquisition) }.to raise_error( AggregateRoot::MissingHandler, - "Missing handler method apply_spanish_inquisition on aggregate ResTesting::Order" + "Missing handler method on aggregate ResTesting::Order for res_testing.SpanishInquisition" ) end end From c70019afe7f125688876e384903ce49351ac5ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 29 Sep 2023 13:58:35 +0200 Subject: [PATCH 57/59] event_store_locator vibes Co-authored-by: Szymon Fiedler --- .../spec/async_handler_helpers_spec.rb | 2 +- rails_event_store/spec/async_handler_helpers_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb b/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb index ff2fb1cfd6..8d722fb58b 100644 --- a/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb +++ b/contrib/ruby_event_store-sidekiq_scheduler/spec/async_handler_helpers_spec.rb @@ -26,7 +26,7 @@ def perform(event) SidekiqHandlerWithHelper.prepend( RailsEventStore::AsyncHandler.with( - event_store: event_store, + event_store_locator: ->{ event_store }, serializer: serializer ) ) diff --git a/rails_event_store/spec/async_handler_helpers_spec.rb b/rails_event_store/spec/async_handler_helpers_spec.rb index c3b70f259d..c532d3adc4 100644 --- a/rails_event_store/spec/async_handler_helpers_spec.rb +++ b/rails_event_store/spec/async_handler_helpers_spec.rb @@ -183,7 +183,7 @@ def perform(event) specify "ActiveJob with AsyncHandlerJobIdOnly prepended with event store locator" do HandlerE = Class.new(IdOnlyHandler) - HandlerE.prepend AsyncHandlerJobIdOnly.with(event_store: nil, event_store_locator: -> { event_store }) + HandlerE.prepend AsyncHandlerJobIdOnly.with(event_store_locator: -> { event_store }) event_store.subscribe_to_all_events(HandlerE) event_store.publish(ev = RubyEventStore::Event.new) From 7fb1478f3894fb11782d20bd4a1a7d1b7402939c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Fri, 29 Sep 2023 13:59:22 +0200 Subject: [PATCH 58/59] rails_event_store_active_record is no more Co-authored-by: Szymon Fiedler --- contrib/dres_rails/Gemfile.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/dres_rails/Gemfile.lock b/contrib/dres_rails/Gemfile.lock index fd6be18f3d..f6985d56dc 100644 --- a/contrib/dres_rails/Gemfile.lock +++ b/contrib/dres_rails/Gemfile.lock @@ -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 From 890dc78475384dc79fb24c96ffedbbc3e574ec99 Mon Sep 17 00:00:00 2001 From: Szymon Fiedler Date: Fri, 29 Sep 2023 15:53:01 +0200 Subject: [PATCH 59/59] Check whether metadata is transformed to binary Mutant had a doubt that Transformation::ProtobufNestedStructMetadata is passed. When not passed, tests would fail on deserialize part not being able to merge timestamp and valid_at to already serialized binary string. No test checked how messages is serialized to prove that transformation is needed. --- contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb b/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb index c55af46a1a..9d1f53876d 100644 --- a/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb +++ b/contrib/ruby_event_store-protobuf/spec/mappers/protobuf_spec.rb @@ -187,7 +187,7 @@ module Mappers expect(record).to be_a(Record) expect(record.event_id).to eq(event_id) expect(record.data).not_to be_empty - expect(record.metadata).not_to be_empty + expect(record.metadata).to match(/\n.+\x00/) expect(record.event_type).to eq("res_testing.OrderCreated") expect(record.timestamp).to eq(time) expect(record.valid_at).to eq(time)