I have an Azure function which process a queue having some records which needs to be inserted into a Database. Its working Fine. But I wanted to use a Timer trigger instead of queueTrigger so that I can check for a record every 30 sec. Can somebody please help me with this. I have tried a basic implementation of the Timer as described in https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer but i don't have an idea how can I process the record.
-
I guess you will have to poll the queue manually in this case. Why do you want this change?Mikhail Shilkov– Mikhail Shilkov2017-05-10 13:07:53 +00:00Commented May 10, 2017 at 13:07
-
same question as @Mikhail why do you need to do this? The idea of having a queue as an input is to even process simultaneously messages in the queue plus when there are no messages to process the function won't run.Christian Melendez– Christian Melendez2017-05-10 15:34:42 +00:00Commented May 10, 2017 at 15:34
-
We are having a large queue(May be million records to be processed at a time or more),so the Function will spin up new Function App instances to handle the load. We want to use the consumption plan as we have a particular batch of data to be imported but after that, there may be no activity in the queue for days. Thus, we wanted to use the Timer so that, only one instance of Function App has been spun at a time. @christian-melendezVivek Sharma– Vivek Sharma2017-05-10 23:35:46 +00:00Commented May 10, 2017 at 23:35
3 Answers
This is the answer that worked for me: There is no direct binding to Azure Queues or ServiceBus Queues when using a Timer Trigger. You have to write the Queue connection and reading logic yourself similar to what you would do if you are not using Functions or Console App. Something similar to the following for reading a single message from a ServiceBus Queue as an example:
var connectionString = "Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=”"; var queueName = "";
var client = QueueClient.CreateFromConnectionString(connectionString, queueName); var message = client.Receive();
Comments
You can bind to CloudQueue via Queue input binding.
Here is a sample code of TimerTrigger that fetches message from the queue.
Function.json
{
"bindings": [
{
"type": "timerTrigger",
"name": "myTimer",
"schedule": "0 * * * * *",
"direction": "in"
},
{
"type": "queue",
"name": "clQueue",
"queueName": "myqueue",
"connection": "",
"direction": "in"
}
],
"disabled": false
}
Run.csx
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Queue;
public static async Task Run(TimerInfo myTimer, CloudQueue clQueue, TraceWriter log)
{
var message = await clQueue.GetMessageAsync();
log.Info($"{message.AsString}");
clQueue.DeleteMessage(message);
}
4 Comments
Based on your last comment, if you definitely don't need to use the queue trigger (remember that it won't matter if you have too many messages, Azure will scale and set the resources needed to process all messages for you, but that can be expensive to run for some time) you can simply upload the same code you'll use for example in a Console App to Azure Functions with all the libraries needed.
Here's an example of how to consume data from a queue in C#: https://learn.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-queues
You'll just need to adapt the code to run as a .csx script (the code you put in the Main method of the console app will be the same code you put in the Run method of the .csx script).