-
Notifications
You must be signed in to change notification settings - Fork 125
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
InMemoryAdapter runs easily into race conditions #188
Comments
@mentero Thanks for your ticket! a) We will definitely need to think about, but I cannot promise solving this soon. |
We have |
Related: *
|
Related:
|
@mentero Also, we would be happy if you fill out our poll about RES usage: https://goo.gl/forms/ecNpJsL5qM2M8Ls93 if you haven't yet :) Thank you and have a great day! |
:( |
The problem is
happening before this
which causes this to fail
|
@mentero indeed. |
I have tried a naive fix and moved calculating |
@mentero I just checked and right now There is no way to use in-memory adapter in a lock-free, unlimited concurrency way. It was not designed like that. Right now We could try to fix it so the I think it would require calling |
@mentero Is that application ever reading those events? Is it ever clearing the always growing in memory list of events? If it is never reading, then you it means you are using RES just as pub/sub without intended persistence. In that case you could substitute a Repository which does nothing and it would work better for the usecase :) I think it might be even beneficial to have such |
@paneq this is some weird mind-reading happening around here... It's dead simple, but first tests show that It'd work just fine. |
And yes, your're absolutely right with:
;) |
Siema Kuba :)
yes, please :) |
Guarantees When there are many threads (or processes) writing concurrently (at the same time) to a stream with expected_version set to :any, all of those writes should succeed. When you later try to read those events you from a stream, you don't have a guarantee about particular order you are going to get them in. Example: If 3 processes A,B,C publish events to stream foo-1 at the same time, all of them should succeed. When you read events from stream foo-1 you will get events A,B,C or A,C,B or B,A,C or B,C,A or C,A,B or C,B,A. Should never fail When a single thread (or process) writes events A, B to a stream, it is guaranteed you will retrieve events A,B in that exact order when reading from a stream. as in http://railseventstore.org/docs/expected_version/ We use lock (mutex) under the hood but that's not an issue. SQL DBs also somewhere deep down might use locks to when updating (uniq) indexes (which ActiveRecordRepository used). So this more closely resembles production behavior of :any Refs: #188
@mentero @siemakuba fixed on master, to be included in next release. Thank you for your contribution. |
Hi, we ran into a problem with using
InMemoryAdapter
today. I prepared an example repository that reproduces the problem.https://github.com/mentero/ruby_event_store_test
Long story short. We have daily workers running at night and we wanted to publish some events from them. We have similar setup to this one. The problem is there are many sidekiq workers running at the same time and we got flooded by
RubyEventStore::WrongExpectedEventVersion
quickly.We have investigated the problem and it seems like a classic race condition caused by
expected_version
being calculated outside of the mutex. It is very easy to run into a scenario where two workers calculate the same version number before entering synchronized block.I don't know why
InMemoryAdapter
was chosen overActiveRecord
one, but nevertheless this behaviour should probably be considered a bug as it makesInMemoryAdapter
very brittle.The text was updated successfully, but these errors were encountered: