Does Azure Function App run several instances at the same time? - azure

If I have a Function app like so
public static class Function1
{
private static readonly HttpClient httpClient = new HttpClient();
[FunctionName("SomeRandomFunction")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
ulong i = 0;
Thread.Sleep(10000);
return (ActionResult)new OkObjectResult($"Hello thread Finished.");
}
}
Are different instances of the function created if different e.g. mobile devices trigger the function at the same time?
I had inferred this from this quote "When you're using the Premium plan, instances of the Azure Functions host are added and removed based on the number of incoming events just like the Consumption plan". I'm on S1 plan.
However when I tested a thread.sleep in function "SomeRandomFunction" like above with two calls for this same function from two different private browser windows, the second call only starts when the first one finished. Why does this happen if it's possible to create several instances of the same function app?
Or is a multi-threading implementation required to have several instances running at the same time?
Thank you

Are different instances of the function created if different e.g. mobile devices trigger the function at the same time?
Yes. From the docs:
The unit of scale for Azure Functions is the function app. When the
function app is scaled out, additional resources are allocated to run
multiple instances of the Azure Functions host. Conversely, as compute
demand is reduced, the scale controller removes function host
instances. The number of instances is eventually scaled in to zero
when no functions are running within a function app.
Azure Functions scale and hosting

Related

Supported bindings for Singleton scopeId on HTTP Trigger Azure Function

I am unclear on how the scopeId parameter of the SingletonAttribute works. Specifically does the scopeId parameter work for HTTP Trigger Azure Functions when you bind it to a route parameter? How does the binding work? What variables/values can I bind to?
For example:
[Singleton("{input}", Mode = SingletonMode.Listener)]
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "v1/{input:length(1,30)}")] Microsoft.AspNetCore.Http.HttpRequest req, string input, ILogger log) {
return new OkObjectResult(input + " world");
}
A HTTP POST request to this function with the URI 'v1/hello' would return: "Hello world".
But would the Singleton attribute work such that all requests to 'v1/hello' would run serially whereas two simultaneous requests with one to 'v1/first' and the other to 'v1/second' would run in parallel?
I see from this answer that for Service Bus Triggers you can bind to properties within the Message object directly.
Also in the documentation there is an example of a Queue Trigger Function with scopeId binding to a property in the WorkItem object.
It's unclear what's supported for HTTP Trigger Functions.
You have two ways to implement singleton mode in Azure function.
The first:
You can do this by setting WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT or maxConcurrentCalls.
Singleton Azure function running as separate instances
The second type:
Create a complete Function project, similar to webapp, and implement it in Configure.
Use dependency injection in .NET Azure Functions
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IMyService>((s) => {
return new MyService();
});
builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
}
}
I got a reply from Microsoft on GitHub: https://github.com/MicrosoftDocs/azure-docs/issues/69011#issuecomment-771922910
"Binding expressions for Singleton have the same behavior as those for general input/output bindings. That is, any binding data from the trigger is available for reference.
In the case of HttpTrigger, that includes any POCO members if you’re binding to a POCO type, as well as any route parameters.
In regards to your code, SingletonMode.Listener is not what you want for your requirement. If you're just trying to serialize individual invocations of the function then you should use the default mode, i.e. [Singleton(“{input}”)].
To answer your question – yes, this would serialize all invocations of v1/hello, allowing v1/first and v1/second to run concurrently."

Implications of separating Http Request-triggered Azure Functions by http verb

I'm still trying to learn about Azure Functions and best practices, but as I understand there are two ways to separate logic by http verb (GET, POST, etc.). Is there a standard or best practice that would prefer either of the two below methods? And more importantly, is there a cost difference between the two methods when running in Azure, assuming the underlying logic stays the same?
Method A:
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
{
if (req.Method == HttpMethods.Get)
{
// do stuff here
}
else if (req.Method == HttpMethods.Post)
{
// do stuff here
}
}
}
Method B:
public static class GetFunction
{
[FunctionName("GetFunction")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req)
{
// do stuff here
}
}
public static class PostFunction
{
[FunctionName("PostFunction")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
{
// do stuff here
}
}
In short the answer to your question about pricing is, IT will be the same for both. It will be equal to the time your logic runs. You should use Consumption plan. If you are looking for cost savings. Microsoft says
"
Azure Functions consumption plan is billed based on per-second resource consumption and executions. Consumption plan pricing includes a monthly free grant of 1 million requests and 400,000 GB-s of resource consumption per month per subscription in pay-as-you-go pricing across all function apps in that subscription."
Here is a link to more details.
https://azure.microsoft.com/en-us/pricing/details/functions/
As far as your second question is concerned. IMO you should use separate functions for get and post. In this way you can separate the endpoints and handle both calls differently. But this kind a breaks the RESTful API practice. So its give and take. :)
You had asked if there is a standard or best practice for using GET or POST. Generally, in REST world, you use GET if you are fetching a resource and POST when you want to create a new resource. So, it basically depends on what you are trying to achieve using the Function. Found a similar questions here > https://stackoverflow.com/a/504993/5344880 and When do you use POST and when do you use GET?
Regarding the pricing, it is based on the number of executions and memory and not by logic. This link will provide more details https://azure.microsoft.com/en-in/pricing/details/functions/ Please do note that there is hard timeout of 10 minutes for Azure Functions
Hope this helps.

Can I create non static Azure function class in C#, what are the consequences?

This non static class is required for constructor injection in Azure function and collection of custom telemetry events.
If we create an azure function app in visual studio, it creates default with static keyword like this:
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
telemetryClient.TrackEvent(new Exception("Function started"));
}
But to use constructor dependency injection (for Temeltry client, i am using it), we need to remove static keyword.
public Function1(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}
Previously, Azure Functions only supported static classes/methods. This restriction made DI via constructor impossible. However later the support for non-static classes/methods was implemented (see Support Instance Functions).
So if you need to use DI via constructor, just change it to non-static. There are no consequences.
This is not entirely true though - I just ran into some trouble with non static timer triggered functions. In my case I needed dependency injection in terms of entity framework, but this non static instance is now causing me trouble in order to call the admin endpoint to trigger the function when doing development locally.
See more on how to normally invoke static timer triggered functions here:
What is the simplest way to run a timer-triggered Azure Function locally once?

How do I post a message to a Azure Service Bus from my Azure function?

I am playing around with Azure functions and trying to setup an intricate construct of pipes and filters (the pattern). I am using Azure functions for this.
My starting point is a HTTP triggered Azure function. That collects some JSON from the body of the request and should pass this message to a Azure Service Bus.
I must be missing something here (I have done this before in RabbitMQ with console apps) but how do I post a message to a service bus from a HTTP triggered Azure function.
I found several references talking about configuring my function.json (what ever that is - im building in Visual Studio).
How does this input/output (trigger/binding) thing work - im guessing that is the problem here...or??
I have my first Azure function in place and is receiving the data from the HTTP - so far so good. But how to proceed?
** Update **
Still cant get it to Work. Got this code and it fails with an http500. (it also says i need to see the og - where is that log?)
public static class EI_WooCommerce_Hub
{
[FunctionName("EI_WooCommerce_Hub")]
[return: ServiceBus("eilogging", Connection = "EIIntegrationServiceBusConnection")]
public async static Task<string> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "EIWooCommerceHub/name/")]HttpRequestMessage req, TraceWriter log)
{
log.Info("Webhook triggered from: ");
return "Hello World to queue";
}
}
** Update 2 **
This seems to be a config problem. In the application settings on the function app I kept getting an authorization error for the servicebus. I added the default "AzureWebJobsServiceBus" setting with the connectionstring, then it worked. It could not pick up my own connection string for some reason.
You should use Service Bus output binding. Since you mentioned Visual Studio, I assume C#. The simplest ever example looks like this:
[FunctionName("ServiceBusOutput")]
[return: ServiceBus("myqueue", Connection = "ServiceBusConnection")]
public static string ServiceBusOutput([HttpTrigger] dynamic input)
{
return input.Text;
}
Then add an application setting called ServiceBusConnection with the connection string to a namespace with queue myqueue (or rename in attribute constructor).
You can find more in Azure Service Bus bindings for Azure Functions - Output.
When you build in Visual Studio, then the function.json is created automatically. All you have to do is to define your triggers and output as attributes of the function parameters (see here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#output)
A minimalistic example:
[FunctionName("HttpTriggerCSharp")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestMessage req,
[ServiceBus("myqueue")] out string sbMessage,
TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
// parse query parameter
string name = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
sbMessage = name;
}

Azure Functions - How to change the Invocation ID within the function?

I have a series of Azure Functions, and I'd like to keep track of them by the InovcationId. In Application Insights, the InvocationId is called the operation_Id.
What I'm trying to do is set the operation_Id to be the same across several different Azure Functions.
I can read this property inside the Azure Function when I pass in ExecutionContext by following this answer, but I can't seem to alter it. Is there some way to change this value from inside the Azure Function?
public static class TestOperationId
{
[FunctionName("TestOperationId")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req,
ILogger log,
ExecutionContext exeCtx
)
{
var input = await req.Content.ReadAsStringAsync();
log.Info(input);
exeCtx.InvocationId = Guid.Parse(input);
return req.CreateResponse(HttpStatusCode.OK);
}
}
The definition for the InvocationId field is defined as
Provides the invocation ID, uniquely identifying the current invocation
Azure Functions doesn't provide changing this, as it would mean that code could override the platform's methods to detect unique invocations of Functions, which would interfere with things like Billing and Metrics for the platform.
It sounds like what you really want is cross-function correlation. There is work being done with the Application Insights team to help support this, but in the meantime, you can see solutions that others are currently utilizing, like here.

Resources