Hi guys,
I’m doing exploratory testing by sending abusive data from the C# client. I can now crash the server every time. It shows this error:
Exit reason: Unexpected error in StorageWriterService: LastEventNumber is less than FirstEventNumber
Parameter name: lastEventNumber
The throw point is in AlreadyCommitted():
public AlreadyCommitted(Guid correlationId, string eventStreamId, int firstEventNumber, int lastEventNumber)
{
Ensure.NotEmptyGuid(correlationId, "correlationId");
Ensure.NotNullOrEmpty(eventStreamId, "eventStreamId");
Ensure.Nonnegative(firstEventNumber, "FirstEventNumber");
if (lastEventNumber < firstEventNumber)
throw new ArgumentOutOfRangeException("lastEventNumber", "LastEventNumber is less than FirstEventNumber");
The error originates in **IndexWriter.**CheckCommit().
if (expectedVersion == ExpectedVersion.Any)
{
// ...
foreach (var eventId in eventIds)
{
// ...
}
return first /* no data in transaction */
? new CommitCheckResult(CommitDecision.Ok, streamId, curVersion, -1, -1, IsSoftDeleted(streamId))
: new CommitCheckResult(CommitDecision.Idempotent, streamId, curVersion, startEventNumber, endEventNumber, false);
}
Here, the foreach loop ends gracefully, and sets the result to CommitDecision.Idempotent, but the last EventInfo retrieved does indeed have an endEventNumber less than startEventNumber. Later on, this causes an unhandled exception.
The client side abuse is to send the same 100000 events repeatedly, sliced into varying sizes.
for (int batchSize = 10; batchSize <= 10000; batchSize *= 10)
{
int loops = 100000/batchSize;
for (int x = 0; x < loops; x++)
{
List<EventData> slice = new List<EventData>(events.Skip(x*batchSize).Take(batchSize));
connection.AppendToStreamAsync(
_streamName,
ExpectedVersion.Any,
slice);
}
}
It always fails on the second pass through the top loop, which I guess makes sense because it is exercising the idempotency checks.
I’m running recent code from the dev branch. Apologies, I cant give an exact version, I wasn’t the one who fetched the source.
Thoughts?
-Sam Kanai