Retrying operations in the eventstore tcp client

I’ve been going through the TCPClient implementation and noticed that correlation ids for the operations are updated on each operation retry.

I was wandering if the following scenario is possible, or I’m overlooking something:

  1. operation A1 (append to stream) sent to server

  2. operation A1 retried as A2

  3. response to A1 returns (success) and is discarded as the operation is no longer present

  4. response to A2 returns (Wrong expected version) and is passed to the calling code



Everything is correct except 4. If A1 succeeded, A2 will succeed (100% guaranteed if you use explicit expected versions, could append twice if you used ExpectedVersion.Any and there was a node failure between A1 and A2 were fired, but in all other cases even with ExpectedVersion.Any you will append only once).

See about idempotency here:

Idempotency is based on message ids. If first has succeeded the second will give the same response (in http as example 201 created). The place where this may not hold true is if you are using expected version.any. This operation is idempotent only withing a limit of messages (say last 100000). If using expectedversion then it’s assured globally and for any duration.

Ok, but then why update the correlation id (correlation id = message id in this case?) of the operation at all when retrying?

No, correlation ID is the ID of request, so you can map requests and responses during async TCP communication. What Greg means by MessageId is EventId of each event, that you pass in EventData.

During retry all event IDs are the same to make idempotency work, but CorrelationId is different exactly to avoid interpreting late response of previous try as a response to retried request.

Oh, ok. Got confused, because I had all of the operations in mind, e.g. StartTransaction, etc.

Thanks for the answers.

StartTransaction/TransactionalWrite/CommitTransaction and AppendToStream batch operation is just two slightly different ways to put data (events in to the system). Idempotency is not coupled to the way you put events in to the system, only to the events itself.