Reputation: 241573
Say I use the deferred messaging feature to send a message at some later future point in time, but then later I might want to cancel that message.
Question 1 - When making the original bus.Defer(...)
call, how do I get a unique identifier back for that message? I would expect there to be a message id or a timeout id of some sort.
Question 2 - Short of calling the RavenDB database directly, is there a way to query the bus to get back all pending deferred messages?
Question 3 - Is there some way to cancel a deferred message? I would expect something like bus.CancelDeferred(messageid)
Is any of this available, or are there any other mechanisms I can use to achieve similar results?
Upvotes: 2
Views: 1587
Reputation: 18628
I've had the need to abandon deferred messages and outstanding replies a few times, and I did it by "incrementing the correlation ID" on my saga. You don't mention sagas though, so I'm not sure if this solution will be usable to you. I do think, however, that it goes under "any other mechanisms" that you ask for :)
Check out this example - here I have the state of my saga which, among other things, contains a custom CorrelationId
:
public class MySagaData : ISagaData
{
// ... the usual stuff here
public string CorrelationId { get; set; }
}
and then, each time I defer a message or request something, I correlate the deferred message and/or reply with the current value of the correlation ID:
bus.Defer(time, new Something { CorrelationId = Data.CorrelationId });
bus.Send(new SomeRequest { CorrelationId = Data.CorrelationId });
thus conceptually correlating the deferred message and the reply with the current state of the saga.
And then, in cases where I want to abandon all outstanding messages, I simply re-set the saga's correlation ID to a new value - I usually set the value to something like somethingWithBusinessMeaning/timestamp
.
This way, abandoned messages will not correlate with any saga instance, effectively being ignored.
Does it make sense?
Upvotes: 4
Reputation: 5273
1) There is currently no way to do this. You could add your own header with a app specific id if you need to keep track of them
2) No, you have to query the storage as you mention. That said what would be the use case for this?
3) No, and this is by design. Given that you can't assume when a message will arrive you can't rely on timeouts being canceled since a defered message might be stuck in a queue and processed right after you cancel. The "cancel" message might also get lost.
In short: your code needs to be prepared to discard "invalid" messages no matter what.
Upvotes: 3