Azure Function and permanent process - azure

I need to update data from external resource and should do it as often as possible.
I created Azure Function with 1-minute timer and marked it as Singleton:
[Singleton]
[FunctionName("FunctionSync")]
public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
but, seems to me, it's being created queue with waiting instances, so it's not good.
Other way - add queue with one message like semaphore and get message on the start add message on the end of function:
[Singleton]
[FunctionName("FunctionSync")]
public async Task Run(
[QueueTrigger("tablet-management-sync-last-datetime", Connection = "StorageConnectionString")]string myQueueItem,
[Queue("tablet-management-sync-last-datetime", Connection = "StorageConnectionString")]CloudQueue outputQueue,
ILogger log
)
{
but this solution is fragile, if something wrong, message is not added to queue and process is stopped.
Which solution is the best?

Azure Functions that are triggered via a TimerTrigger will only be called once per interval, even if there are multiple instances. So this is something that you don't have to worry about. It does this using Blob Leases, and you can read about it here on the webjob sdk wiki.

Related

How to configure scheduled azure webjob to run one instance?

I deployed a continuos Azure WebJob with one function triggered by TimerTrigger with CRON set to run every 2 minutes.
public async void ProcessScheduledNotifications([TimerTrigger("%Api.Settings.Crontab%", RunOnStartup = false, UseMonitor = false)]
TimerInfo timerInfo, TextWriter log)
{
However, my code calls external API and it may take more than 2 minutes to finish. I found that even when one instance is running, the next instance is triggered after 10 minutes.
It there a way to disable this behavior?
TimerTrigger uses the Singleton feature of the WebJobs SDK to ensure that only a single instance of your triggered function is running at any given time.you can use [Singleton] attribute on your functions.The [Singleton] attribute will restrict a function to only run one at a time across all instances, but do be aware that if you're on a Consumption Plan then you'll be charged for the runtime of any instance waiting for another instance to complete, which could significantly increase your costs .
[Singleton]
public async void ProcessScheduledNotifications([TimerTrigger("%Api.Settings.Crontab%", RunOnStartup = false, UseMonitor = false)]
TimerInfo timerInfo, TextWriter log)
{

Handling errors/failures occurred in Azure Durable Functions called by queue-triggered Azure Functions

We have an Azure Storage Queue which triggers an azure function once a payload/message hits the queue. The queue-triggered function invokes another durable function to process the message/payload.
Here it is the code snippet:
[FunctionName("QueueTriggerFunction")]
public Task QueueTriggerFunction(
[QueueTrigger("MyQueue", Connection = "MyStorage")]string item,
[OrchestrationClient] DurableOrchestrationClient client,
ILogger log)
=> client.StartNewAsync("Processor", JsonConvert.DeserializeObject<MyObject>(item));
And the durable function looks like the following code sample:
[FunctionName("Processor")]
public async Task ConcurrencyProcessorAsync(
[OrchestrationTrigger] DurableOrchestrationContext context,
ILogger log)
{
var myObject= context.GetInput<MyObject>();
if(ObjectProcessor(myObject) == false)
{
throw new Exception("Processor failed");
}
}
I'd like the payload to end up in the poison messages queue if the exception above is raised upon failing the ObjectProcessor method but it's not happening in reality because the exception does not bublle up through the orchestrator client. Any suggestions on how to make this exception thrown back to the caller function which is a queue-triggered one to make the payload appear in the poison messages queue?
You can't.
The QueueTriggerFunction just starts the Orchestration. After that it's life cycle ends.
I believe you can directly add your payload to poison queue using either Azure Storage Services REST API or this .Net library
Please note that name of poison queue == $"{queueName}-poison"

Sequence processing with Azure Function & Service Bus

I have an issue with Azure Function Service Bus trigger.
The issue is Azure function cannot wait a message done before process a new message. It process Parallel, it not wait 5s before get next message. But i need it process sequencecy (as image bellow).
How can i do that?
[FunctionName("HttpStartSingle")]
public static void Run(
[ServiceBusTrigger("MyServiceBusQueue", Connection = "Connection")]string myQueueItem,
[OrchestrationClient] DurableOrchestrationClient starter,
ILogger log)
{
Console.WriteLine($"MessageId={myQueueItem}");
Thread.Sleep(5000);
}
I resolved my problem by using this config in my host.json
{
"version": "2.0",
"extensions": {
"serviceBus": {
"messageHandlerOptions": {
"maxConcurrentCalls": 1
}
}
}}
There are two approaches you can accomplish this,
(1) You are looking for Durable Function with function chaining
For background jobs you often need to ensure that only one instance of
a particular orchestrator runs at a time. This can be done in Durable
Functions by assigning a specific instance ID to an orchestrator when
creating it.
(2) Based on the messages that you are writing to Queue, you need to partition the data, that will automatically handle the order of messages which you do not need to handle manually by azure function
In general, ordered messaging is not something I'd be striving to implement since the order can and at some point will be distorted. Saying that, in some scenarios, it's required. For that, you should either use Durable Function to orchestrate your messages or use Service Bus message Sessions.
Azure Functions has recently added support for ordered message delivery (accent on the delivery part as processing can still fail). It's almost the same as the normal Function, with a slight change that you need to instruct the SDK to utilize sessions.
public async Task Run(
[ServiceBusTrigger("queue",
Connection = "ServiceBusConnectionString",
IsSessionsEnabled = true)] Message message, // Enable Sessions
ILogger log)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {Encoding.UTF8.GetString(message.MessageId)}");
await _cosmosDbClient.Save(...);
}
Here's a post for more detials.
Warning: using sessions will require messages to be sent with a session ID, potentially requiring a change on the sending side.

Manually trigger time based Azure Functions on dev [duplicate]

This question already has answers here:
What is the simplest way to run a timer-triggered Azure Function locally once?
(9 answers)
Closed 1 year ago.
My task runs once a day when deployed. For development currently I just changed the CRON to "every minute" and wait for that minute to hit in order for the function to be triggered for me to do the debugging. Is there a way such that I can leave my timer code to stay as "Every day" but still be able to kick it off manually.
In Azure I can just go to the function resource and click "Run" that will start it regardless of the timer. I am looking for something similar on my dev.
You are probably looking for this on the Timer Trigger attribute,
[TimerTrigger("", RunOnStartup = true)]TimerInfo timer
That should kick it off on startup.
It doesn't look like there is a direct solution available to manually (or even through and http request) trigger a time based Azure function.
Possible Workaround
Have a second http triggered function that has the same logic/code. You can use this 2nd function for testing on demand basis.
Please see the discussion in these 2 threads, it's very relevant to you -
Any method for testing timer trigger function
Time triggered azure function to trigger immediately after deploy
As #neo99 mentioned, simple answer is it is not possible just out of the box. The reason is input parameters for Run method of Trigger function are different for different type of triggers.
For e.g. you are looking to manually trigger(HttpTrigger) a TimerTrigger
Timer Trigger:
[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, TraceWriter log)
Http Trigger:
[FunctionName("HttpTriggerCSharp")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req,
TraceWriter log)

Azure WebJobs Scheduler

Can we have multiple Schedules in a Single web Job of Microsoft Azure.
We have certain functionalities to happen in a single job within particular time
i.e multiple schedules so we have tried through the timer but i need to know is there any other option.Thank you
You can use the TimerTriggerAttribute: Please refer https://github.com/Azure/azure-webjobs-sdk-extensions#timertrigger
// Triggered every hours
public static void HourlyTimerJob([TimerTrigger("00:01:00")] TimerInfo timerInfo, TextWriter log)
{
log.WriteLine("Your first scheduled job!");
}
// Triggered every 15 minutes
public static void MinutelyTimerJob([TimerTrigger("00:00:15")] TimerInfo timerInfo, TextWriter log)
{
log.WriteLine("Your second scheduled job!");
}
You can always use CRON expression for web jobs to e.g., let it run at particular times. You can refer to this official doc.

Resources