Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix projections with bi-temporal event stream #1565

Closed
wants to merge 1 commit into from

Conversation

alexdreher
Copy link
Contributor

Projections don't play with bi-temporal event sourcing at all.

I followed the discussions and tickets from RES 3.0 ( #1463 + #1552 + #1561) and I know, that this will become obsolete, when the "Projections redesigned" (f76c43d) is merged.

Then we can finally use:

  Projection
    .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).as_of)

But for now, I would appreciate this fix, if there is nothing against it.

Please have a look at the changed specs, as I don't know if we really need time_sort_by=nil.

When using non-bi-temporal events (without valid_at) the projection is now ordered by timestamp (but sadly, this doesn't fix #1550)

@mostlyobvious
Copy link
Member

I would appreciate this fix, if there is nothing against it.

It is changing the behaviour, so to keep our Semantic Versioning promise we cannot release it in 2.x series. If that's needed in your current project, I'd suggest patching this functionality specifically in the application.

Adding version check, either in runtime or a as a unit test would keep everyone alert when upgrading RES to see if the patch applies (it should, we're going to keep SemVer promise).

raise "check RubyEventStore::Projection#read_scope implementation drift and bump version check" unless RubyEventStore::VERSION == "2.9.0"

module AsOfReadScope
  def read_scope(*, **)
    super.as_of
  end
end

RubyEventStore::Projection.prepend(AsOfReadScope)

@mostlyobvious
Copy link
Member

I don't know if we really need time_sort_by=nil

There's a guaranteed monotonicity by the means of sequence numbers in the database table. It is mostly the same as the monotonicity of created_at timestamp.

However sorting by timestamp is less accurate when:

  • timestamp resolution is low (i.e. seconds)
  • multiple events share same timestamp, when appended in batches

I'd still keep sorting by ids and timestamps separate.

@alexdreher
Copy link
Contributor Author

Makes sense and is another good reason for the redesign of projections.

Thanks @pawelpacana for the monkey patch, it is working as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RubyEventStore::Projection does not yield events in deterministic order when using multiple streams
2 participants