EventId idempotence check

Hi there!

I think I found a small problem in the eventId idempotence mechanism. I tested this with an empty database and can reproduce the problem every time.

My setup:

ES VERSION: 3.0.0.0 (master/8ef23af341976d4f92580cdae28921bd0e325393, Wed, 15 Jan 2014 13:31:15 +0000)

OS: Windows (Microsoft Windows NT 6.1.7601 Service Pack 1)

RUNTIME: .NET 4.0.30319.18408 (64-bit)

GC: 3 GENERATIONS

Step 1) HTTP POST to http://localhost:2113/streams/foobar-1 three times in a row

Body:

[{
eventType: “FooBar”,
eventId: “2cf4a1a2-b4a3-5dfe-a01f-ec52c34e16e6”,
data: {
foo: “bar”
}
}]

``

The result is as expected: only one event in the stream foobar-1

Step 2) POST the exact same document to http://localhost:2113/streams/foobar-2 three times in a row

The result will be three events in stream foobar-2, where there should be only one.

For documents with a different eventId than the one above the idempotence check will work fine, only if we try the above id again the check will fail.

Sebastian,

do you specify a ES-ExpectedVersion http header?

-yuriy

Hi Yuriy,

I just saw the remark here https://github.com/eventstore/eventstore/wiki/Writing-to-a-Stream-%28HTTP%29#idempotency, that Event Store is only 100% idempotent when using ES-ExpectedVersion. Well, I guess that explains my problem :slight_smile: But still, I’m curious, what is so special about my scenario that ES is not able to check this specific eventId?

Thanks

Sebastian,

I’m going to check this.

-yuriy

Chris, Sebastian,

I can reproduce the described behavior. The problem with this scenario is that you are attempting to post the same event with the same eventId into multiple streams. This breaks the EventStore idempotency mechanism.

The idempotence check is intended to ensure that if you retry the post event request the event is not posted twice. However posting the same event into two different streams is not considered as retrying a post request. The behavior is undefined in this case as eventId must be unique.

I verified that posting the same event to the same stream three and more times doe snot break the idempotence chech.

-yuriy

Thanks Yuriy,

so posting the same event multiple times to the same stream should always result in only one event stored in the stream, even without expected version?

Sebastian

It is not guaranteed, but you should not observe this without heavy load on the system and without long delay between the first request and the retry. If you need guarantees you need expected version.

Yuri,

I’m experiencing a weird behavior. When executing the test below, two events are added to EventStore. I also tried it with ExpectedVersion.Any, but the behavior persists. This only happens with the first event.

1 1@Calendar-d6f76d1332934ab1b32df623fb6d66f1 Created 2014-02-06 19:07:44

0 0@Calendar-d6f76d1332934ab1b32df623fb6d66f1 Created 2014-02-06 19:07:44

[]

let create a new Calendar () =

let version = 0

Calendar.Create(tenantId, “Calendar 1”) |> handleCommand (calendarId,version)

if expectedVersion = 0 then conn.AppendToStreamAsync(streamId, ExpectedVersion.NoStream, eventData)

Setup:

EventStore 2.0.1

Windows 8.1

NET Framework 4.5

Att,

Antonio Mattos

Antonio,

Do you say than a single AppendToStreamAsync appends two events?

Exactly. The first time I execute the test case it appends the event twice. However, if I try to execute it again it won’t write the event as expected. This happens only with the first append event (first execution of this test case), the other test cases are all appended once and only once.

Antonio,

Could you extract only the essential code that I can try myself? F# is fine.

Yuriy,

I uploaded a sample to a github repo: https://github.com/antonioj-mattos/exemplo

The repository framework is based on Euler’s work at: https://github.com/eulerfx/DDDInventoryItemFSharp.

Yuriy,

I found the problem, ES works just fine. It happens I used Euler’s new version of the repository, which seems to have a missing check. I should be more careful when updating the code base. I’m Sorry for taking your time with such a silly problem.