diff --git a/src/ServiceControl/MessageFailures/Api/EditFailedMessagesController.cs b/src/ServiceControl/MessageFailures/Api/EditFailedMessagesController.cs index 9c0413cbac..533f2c8792 100644 --- a/src/ServiceControl/MessageFailures/Api/EditFailedMessagesController.cs +++ b/src/ServiceControl/MessageFailures/Api/EditFailedMessagesController.cs @@ -27,7 +27,7 @@ public class EditFailedMessagesController( [Route("edit/{failedMessageId:required:minlength(1)}")] [HttpPost] - public async Task Edit(string failedMessageId, [FromBody] EditMessageModel edit) + public async Task> Edit(string failedMessageId, [FromBody] EditMessageModel edit) { if (!settings.AllowMessageEditing) { @@ -35,6 +35,16 @@ public async Task Edit(string failedMessageId, [FromBody] EditMes return NotFound(); } + //HINT: This validation is the first one because we want to minimize the chance of two users concurrently execute an edit-retry. + var editManager = await store.CreateEditFailedMessageManager(); + var editId = await editManager.GetCurrentEditingMessageId(failedMessageId); + if (editId != null) + { + logger.LogWarning("Cannot edit message {FailedMessageId} because it has already been edited", failedMessageId); + // We return HTTP 200 even though the edit is being ignored. This is to keep the compatibility with older versions of ServicePulse that don't handle the payload. + return Ok(new EditRetryResponse { EditIgnored = true }); + } + var failedMessage = await store.ErrorBy(failedMessageId); if (failedMessage == null) @@ -45,8 +55,8 @@ public async Task Edit(string failedMessageId, [FromBody] EditMes //WARN /* - * failedMessage.ProcessingAttempts.Last() return the lat retry attempt. - * In theory between teh time someone edits a failed message and retry it someone else + * failedMessage.ProcessingAttempts.Last() return the last retry attempt. + * In theory between the time someone edits a failed message and retry it someone else * could have retried the same message without editing. If this is the case "Last()" is * not anymore the same message. * Instead of using Last() it's probably better to select the processing attempt by looking for @@ -74,7 +84,7 @@ await session.SendLocal(new EditAndSend NewHeaders = edit.MessageHeaders }); - return Accepted(); + return Accepted(new EditRetryResponse { EditIgnored = false }); } @@ -137,4 +147,9 @@ public class EditMessageModel public Dictionary MessageHeaders { get; set; } } + + public class EditRetryResponse + { + public bool EditIgnored { get; set; } + } } \ No newline at end of file