Running some startup tasks in Configure of Azure FunctionsStartup

Viewed 120

I have a function that is bound to a QueueTrigger. In this function I generate a file and write this to a Blob Storage.

But before writing (uploading) the file I want to make sure that the container exists. Is the Configure method in the startup class that inherits FunctionsStartup the right place? It feels wrong to do it every time the trigger runs, isn't it?

I'm using DI to supply my function class some services.

[FunctionName("MyFunction")]
public async Task Run([QueueTrigger(MyQueueName, Connection = "AzureWebJobsStorage")]
    MyObject queueMessage, ILogger log)
{
    var bytes = Encoding.UTF8.GetBytes("MyFileContent");

    // Check if container exists - but not everytime?

    var blobClient = new BlobClient(_settings.ConnectionString, _settings.ContainerName, _settings.FileName);

    await using var memoryStream = new MemoryStream(bytes);
    await blobClient.UploadAsync(memoryStream, true);
}
using MyApp.FunctionApp;
using MyApp.FunctionApp.Options;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(Startup))]

namespace MyApp.FunctionApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // Some startup tasks here like ensuring existence of a Blob Container?
            
            builder.Services.AddOptions<Storage>().Configure<IConfiguration>((settings, configuration) =>
            {
                configuration.GetSection("Storage").Bind(settings);
            });
        }
    }
}
1 Answers

Depending on the frequency of how often you want to check, you could even do something as simple as this:

//shared variable for all instances that run on the same VM
private static bool HaveCheckedBlobContainer = false;

Then, on each invocation:

if (!HaveCheckedBlobContainer)
{
   //perform check ...
   HaveCheckedBlobContainer = true; 
}

I'll generally have an Initialize() method to set up some expensive instances that need to be stored in static member variables. I'll call Initialize() on each invocation, and use a check such as

_someMemberVariable ??= getItFromMyDiContainerOrInstantiateId();

So that it's only executed once, regardless of invocation count.

Related