Skip to content

Conversation

Copy link

Copilot AI commented Sep 4, 2025

Problem

When using messageBus.ScheduleAsync(msg, delay) or calling ReScheduleAsync() within a message handler that uses database-backed scheduling (DurableInbox), Wolverine would throw duplicate key exceptions. This occurred because the rescheduling logic was attempting to insert a new envelope entry rather than updating the existing one.

public async Task Handle(SomeMessage message, IMessageContext context)
{
    // This would cause a duplicate key exception with DurableInbox
    await context.ReScheduleAsync(DateTimeOffset.UtcNow.AddHours(1));
}

The issue was that ReScheduleAsync() was calling ScheduleJobAsync() which creates new envelope entries, instead of ScheduleExecutionAsync() which updates existing envelopes.

Solution

This PR fixes the core issue and improves the developer experience:

Core Fix

  • Modified MessageContext.ReScheduleAsync() to use ScheduleExecutionAsync() instead of ScheduleJobAsync() for non-native scheduling scenarios
  • ScheduleExecutionAsync() updates the existing envelope's execution time rather than creating a duplicate entry
  • The fix only affects database-backed scenarios; native scheduling (like Azure Service Bus) continues to work as before

Developer Experience Improvements

Added convenient extension methods on IMessageContext for easier discoverability:

public async Task Handle(SomeMessage message, IMessageContext context)
{
    // Reschedule to a specific time
    await context.RescheduleAsync(DateTimeOffset.UtcNow.AddHours(2));
    
    // Reschedule with a delay
    await context.RescheduleAsync(TimeSpan.FromMinutes(30));
}

Changes Made

  1. Fixed duplicate issue: MessageContext.ReScheduleAsync() now calls ScheduleExecutionAsync() for database-backed scenarios
  2. Added convenience methods: Two new extension methods on IMessageContext for rescheduling
  3. Updated tests: All existing tests updated and new tests added for convenience methods
  4. Minimal impact: Only one line changed in the core implementation

Testing

All rescheduling tests pass, including:

  • Rescheduling with native scheduling support
  • Rescheduling without native scheduling support (database-backed)
  • New convenience method tests for both DateTimeOffset and TimeSpan overloads

The fix resolves the duplicate envelope issue while maintaining full backward compatibility and improving the developer experience.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] I'm checking for options to reschedule specific message/Envelope inside wolverine's handlers in simmilar fashion like the current scheduling works messageBus.ScheduleAsync(msg, delay). If I see correctly from the source code, it seems that ScheduleAsyn... Fix duplicate envelope exception when rescheduling messages in database-backed scenarios Sep 4, 2025
Copilot AI requested a review from punxrok September 4, 2025 07:28
punxrok

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants