LockToken expires before LockUntilUtc time in azure service bus - azure

I am using windows azure service bus for messaging. We have created web api to pull the messages from service bus. Mobile app is using this web api for getting messages. We are using PeekLock mode in subscription client and the lockduration is 5 minutes.
On client side if messages takes more than 5 minute to process then message will unlock. So before it unlock we want to renew the Lock. So we have created another web api to renew the lock. In web api we are passing the LockToken. But when we use subscriptionClient.RenewMessageLockAsync(new Guid(lockToken)), it throws error "The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue" before the Lock expiration time. We are initiating the renew lock before 1.5 min of message LockUntilUtc time.
My question here is can we renew the message lock before it expirytime? And if yes then why azure service bus throwing lock expired error? Please help me to understand this renew lock things.

You can extend the lock manually, but you need to make sure it happens before the server is unlocking it.
Another option, which I personally prefer more, is to use OnMessage API. It allows you to specify OnMessageOptions.AutoRenewTimeout which will be an extension time in case your callback that handles the message is not done. OnMessage API will also ensure that extension is invoked if you're about to exceed lock duration. This way you also won't need to have another web API, which sounds a little off.
Have a look at the recent post I wrote on this API.

Related

App Service Plan Create operation is throttled for subscription

I have been testing around with the Azure App Services and got this error
App Service Plan Create operation is throttled for subscription.
As I understand I created too many apps in a short period, how long until I can create a new app again?
Thank you
I began receiving this error, but without the Retry-After property in the response. After working with Azure support, it turns out newly-created subscriptions take a while to fully allocate in the background. We had to wait 48 hours before the throttling error would go away, and that was what Azure support validated with us.
Once the 48 hours passed (and the new Azure sub was presumably complete in its creation), we no longer received the errors.
As I understand I created too many apps in a short period, how long
until I can create a new app again?
We dont have any ideal time that how long until you have to wait to create a new app again.
Throttling happens at two levels. Azure Resource Manager throttles requests for the subscription and tenant.
When you reach the limit, you receive the HTTP status code 429 Too many requests. The response includes a Retry-After value, which specifies the number of seconds your application should wait (or sleep) before sending the next request. If you send a request before the retry value has elapsed, your request isn't processed and a new retry value is returned.
You can determine the number of remaining requests by examining response headers. Read requests return a value in the header for the number of remaining read requests. Write requests include a value for the number of remaining write requests.
You refer this documentation,on how to Retrieving these header values in your code.

Azure Service Bus: Delete Session Messages

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

Peek and Complete Message using different Receiver Instances - Azure Service Bus

Scenario
When business transactions are performed, we're supposed to make that data available to end clients.
Current Design
Our web app publishes transaction messages are added to a topic on the Azure Service Bus.
We expose APIs to clients through which they can consume the data from those transactions.
Upon calling these APIs, we read the messages from the Subscription and return it to the client.
Problem
We want a guaranteed delivery - we want to make sure the client acknowledges the delivery of the data. So we don't want to remove the message from the subscription immediately. We want to keep it until the client acknowledges it.
So we only want to do a "Peek" instead of "Receive".
So the client calls the first API, to get the data, where we do a Peek.
And once the client has received the packets, the client would call a second API, to acknowledge.
At this point, we want to remove the message from the Subscription, making it Complete.
The current design of the Service Bus Message Receiver is that, a Complete can be performed only using the same Receiver instance that performed the Peek, as per the documentation, and we also observed the same when we tried it out.
Both the APIs, are two separate APIs and we cannot do the Peek and Complete using the same instance of the Receiver.
Thinking about options to somehow make the Receiver as a Singleton, across APIs within that App Service.
However this will be a problem when the App Service scales out.
Is there a different way to achieve what we're trying to do here ?
There is an option available in Azure Service Bus to defer messages. Once a message is deferred, it can be received with the help of it's sequence number.
The first client should receive the message and instead of completing it, it should defer it and return it.
The second client (which has sequence number) can receive the message from the Subscription. Refer here for more details.
Another option would be to not use a Service Bus Client on your backend and instead your clients could directly work with Service Bus using its Service REST API (assuming they can't use the AMQP client if I am understanding your scenario correctly).
There are APIs to
Peek-Lock
Renew Lock
Unlock
Delete (Complete)
You could also proxy these requests if you'd like using your backend itself or a service like APIM if you are already using it.
PS: Cross posting the answer for the same query on the MSDN forum

How to renew the lock after the lock duration has expired? Using Azure Service Bus Session Queue

Currently I am using Azure Service Bus Session Queue by configuring the 30 seconds as a lock duration.
For example, I have one session with 3 messages
While processing the first message to took more time, after that I am calling CompleteAsync() for deleting the message from the queue. But whenever I execute CompleteAsync(), I am getting SessionLockLostException.
await session.CompleteAsync(message.SystemProperties.LockToken);
I want to renew the lock whenever lock has expired.
I followed this documentation, but I am not getting any sample for renew lock token.
I want to renew the lock whenever lock has expired.
Not possible. Once lock token has expired, the broker will consider it unlocked and serve to other consumers. Instead, you should review your configuration and design approach. If you receive messages that can take longer to process, don't use MaxLockDuration of 30 seconds, up it up. If 5 minutes is not sufficient, look at either extending the lock time manually before it expires, or if using the built-in message pump, configure the maximum time to auto-renew the lock.

Run scheduler on Azure based on user specific scheduled time

We have an API to fetch the latest transaction data of the user based on the scheduled Next_Refresh_Time. Each user has different scheduled refresh time. Since we have thousands of users we have to run the scheduler to fetch the data. Please suggest me the best way to do it.
Each user has different scheduled refresh time. Since we have thousands of users we have to run the scheduler to fetch the data.
You could add a queue message and specify initialVisibilityDelay with Next_Refresh_Time value when a user login, and then you could create and run a Queue-trigger WebJob to process queue message and featch the latest data (and if current user is still online, add the message (specify same content and initialVisibilityDelay as original message) to queue).
Besides, if you’d like to real-time push the latest data to specific connected user, SignalR would help you implement real-time functionality and SignalR can be used in a variety of client platforms. You could save connection id of a login user in queue message, and then you can call hub method in WebJob function to push data to a connected user based on connection id.
The following thread and article would be helpful to know how to establish connection and call hub method.
SignalR - Broadcasting over a Hub in another Project from outside of
a
Hub
Hubs API for
SignalR

Resources