0
votes

I have a stateless RESTful service that will Peek & Lock off of an Azure Service Bus queue. After it gets the message, it will forward the message on to a client who will process it. The client may take longer than the lock timeout to process the message.

The client cannot talk to the queue directly and I would prefer to not add any state to the service. Instead, I want to send enough information to the client such that they can send it back and the service can renew the lock on their behalf.

So, how do I serialize a BrokeredMessage such that I can renew the lock on it after deserializing it?

Alternatively, is there some way I can get a token for a BrokeredMessage such that I can renew the lock or delete the message from the queue using just that token (rather than the entire message)?

2

2 Answers

2
votes

Per the Azure Service Bus REST API reference, the renew action requires the MessageId and the LockToken, both of which are available as properties on the BrokeredMessage object. You should be able to use those to fire off a REST request to renew your lock.

0
votes

All you need to abandon a message is the lock token which is just a Guid so it serializes nicely. Using the Azure Service Bus SDK (via NuGet) the following test will pass if run multiple times in a row on a queue with one message in it. If you remove the queueClient.Abandon(lockToken) line then the test will fail on every run after the first until the lock times out (1 minute default). This is because brokeredMessage is null since there are no messages available to be received as long as the one message in the queue has a lock taken out on it.

[Fact]
public void receive_lock_abandon()
{
    const String connectionString = "Endpoint=sb://stayupdated.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=X/LX7IFHLADiAMgn5zGoSlCYCriwa68An1hijB3rGXQ=";
    const String queueName = "TestQueue";

    var receiveClient = QueueClient.CreateFromConnectionString(connectionString, queueName);
    var brokeredMessage = receiveClient.Receive(TimeSpan.FromSeconds(1));
    var serializedLockToken = brokeredMessage.LockToken.ToString();

    var lockToken = Guid.ParseExact(serializedLockToken, "D");
    var queueClient = QueueClient.CreateFromConnectionString(connectionString, queueName);
    queueClient.Abandon(lockToken);
}