I've looked everywhere for information on this but can't seem to find what i'm looking for.
I've got an azure topic, with one subscription.
The handler for the subscription failed some messages, they've been put on the deadletter queue.
I can access the messages but i'm at a loss for how to restore them.
I don't want to create a copy of the message and send it to the topic. I specifically want to move it to the subscription queue it came from.
Is there any way to do this?
I don't know if this is possible.
What we mostly do to handle & resume messages, is to use the pattern of defering messages. If a handler fails a message, he can then defer the message and keep track of the messagesequence number (typically in a management / tracking database or component).
Whenever the message needs to be reprocessed (retried), a receiver can then specifically get that message (using the same defered message id) and process it again.
Related
I am using Azure Service Bus with .NET core
In our application, we are sending Session Messages to Service Bus. Whenever we receive a cancellation request with the session-Id, we need to remove/delete/complete messages with that specific sessionId without any further processing
I tried to access the MessageSession from another receiver to cancel messages from the queue
But I got error - The requested session 'session-name' cannot be accepted. It may be locked by another receiver.
Is there any other possible way to delete messages from service bus queue with a specific sessionId (session may be locked in few cases)
The only workaround, I'm able to get is
Update in database stating sessionId is cancelled & checking this for each message.
But this is not efficient for a large number of messages, as we need to extra DB hit for each message.
Is there any other possible way to delete messages from service bus queue with a specific sessionId?
It is possible to delete the message with SessionId using a search feature in Serverless360 where you can specify the query as SessionId = "1" and retrieve the message and delete it. But, it is obvious that you cannot retrieve session messages when it is locked and hence your second test case is not possible anyhow unless you could manage to use some action like renew lock in your orchestration with some delay in processing the messages.
Below is the screenshot of sample orchestration where each time the lock gets renewed and hence you can retrieve the message once you have the Session-Id
I have several subscriptions that listens to different Topics for messages, and some of this messages are dependent on each other. So one message for one subscription "needs" to arrive before another messages in another subscriptions.
I could solve this by storing the messages temporary in a database, but I thought that if I get a message on one subscription and it's correlated messages on a another subscription hasn't arrived yet, I would just wait 1 second and put the first messages back on it's subscription so the correlated messages get's some more time to arrive first.
It's easy if it would have been a Queue, but now it's a subscription and that client don't have any "Send" methods on it.
I don't want to put the messages back on the Topics, since other subscription might not want that messages again.
Since subscriptions basically is a Queue it should be possible, so is there some "base object" that could be used to put messages directly to a subscription queue.
Best Regards
Magnus Gladh
While subscription is a queue behind the scenes, you cannot send messages directly to that queue. Instead, you should target a topic.
If you wish to abort the receive operation, you can when receiving in PeekLock mode.
In Azure Service Bus, if below is the sequence of events, then all's fine -
Create Topic
Create Subscriptions inside Topic
Send Messages to Topic
With above, the subscriptions are triggered when a message is sent. This is expected.
However, if we modify the above sequence like this
Create Topic
Send Messages to Topic
Create Subscriptions inside Topic
In this case, as messages are sent to a topic whilst no subscriptions were in place, when the subscriptions are indeed created, the previously sent messages don't show up in their list. Those messages are essentially 'lost'. Am not able to see those messages in Service Bus Explorer too.
The above sequence flow is relevant because we have detached publishers and subscribers, where the publisher just sends a message and subscribers, when they come online, create the subscriptions and handle them. The order in which the publisher and subscriber come online is not guaranteed.
How can I access/process messages sent to the topic before the subscriptions are created? What happens to such messages in the first place?
Thanks
It turns out that the above behavior is by design - if no subscriptions are there, then the message is lost.
To overcome this, Azure Service Bus provides a property on topic to enable the pre-filtering of messages before they are sent. So, if no filters/subscriptions are available, it'll throw an exception
Set the option on the Topic
namespaceManager.CreateTopicAsync(new TopicDescription(topicName)
{
EnableFilteringMessagesBeforePublishing = true
});
Whilst sending the message, check for exception
try
{
await topicClient.SendAsync(brokeredMessage);
}
catch (NoMatchingSubscriptionException ex)
{
// handle the exception, maybe send it to dead letter queue using DeadLetterAsync
}
I'd like to change a message property before abandoning. The following code don't work. I'm receiving the message with the initial Label.
message.Label = "failed";
message.Abandon();
It it possible to define that message was abandoned?
You cannot update content of an Azure Service Bus Queue message object. Frankly, if I have to update a message content, than there is something wrong in my approach.
You can, however, update the content of an Azure Storage Queue message, using the UpdateMessage method or any of its async friends. In any case, I feel wrong the general approach of touching message content!
For your purpose I suggest that you take a look at DeadLetterQueue feature of Azure SErvice Bus Queues and Topics, or the DequeueCount property of Azure Storage message to determine whether there is something wrong with the message.
Is it possible to send a message directly to a Subscription queue?
Scenario:
A message failed, dropped onto the deadletter, the message has been picked up manually using defer, cloned and needs to be sent to the queue it was first deadlettered on, but NOT the topic.
Can I send a message directly to a subscriber?
I've considered creating a separate retry queue per subscriber, where the handling service will also receive messages from but i'd rather not do this.
this is a similar question to the one you asked earlier: Azure Service Bus Subscriber Deadletter
this is not possible, as far as I know. the only thing you could do is to add an extra filter on every subscription that has something like SubscriptionName='SubscriptionA'. If you then want to send you deadlettered message to the specific subscription, you can add a property SubscriptionName to it, to achieve your goal. Take into account that you also have to make sure that in your original filter, you add a condition to indicate that the property SubscriptionName should not exist.
I agree however, that it would be a nice scenario to 'undeadletter' a message, so that it ends up again in his original subscription.