0

The user inputs the CRON expression from an interface. The function app should update the appsettings to reflect the user input.

My current approach

The TimerTrigger function with schedule appsetting

    [FunctionName("Cleanup")]
    public static async Task Run([TimerTrigger("%schedule%")]TimerInfo myTimer, ILogger log)
    {
        // Get the connection string from app settings and use it to create a connection.
        var str = Environment.GetEnvironmentVariable("db_connection");
        log.LogInformation($"db_connection : {str}");
    }

Setting the schedule appsetting via environment variable

    [FunctionName("SetConfig")]
    public static async Task<HttpResponseMessage> SetConfig([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req)
    {
        HistoryLogDeleteConfigDto data = await req.Content.ReadAsAsync<HistoryLogDeleteConfigDto>();
        Environment.SetEnvironmentVariable("schedule", data.Schedule);

        return req.CreateResponse(HttpStatusCode.OK);
    }

local.settings.json file

"Values": {
"db_connection": "Server=DESKTOP-DFJ3PBT;Database=CovalentLogger;Trusted_Connection=True;MultipleActiveResultSets=true",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"schedule": "*/20 * * * * *"
}       

POSTMAN request body to update the schedule appsetting

{
"Schedule": "*/30 * * * * *"
}

But no luck. After sending the request from postman to update the setting, if I access the azure portal function app setting I still can see the old value.

But if I query the environmnet variable like below Environment.GetEnvironmentVariable("schedule", EnvironmentVariableTarget.Process) I can see the new expression. But in Azure portal function appsetting it stills the old value. So the job still executes based on the old schedule.

Where have I gone wrong? Thank you

Isuru
  • 950
  • 1
  • 13
  • 34

1 Answers1

1

I don't think updating the Environment variable like that will work as the the schedule is only being read at the initialization of the Function - or when the app setting is updated on the app service. However, it should still be fairly doable. This does basically exactly what you are looking for: https://stackoverflow.com/a/50116234/1537195

Just package this in your HTTP-triggered Function (and I'd probably use Managed Identity) and you are good to go.

silent
  • 14,494
  • 4
  • 46
  • 86
  • Thanks! I went with this and all is working. The only problem is Azure takes minutes to update the appsettings. Even-though it might be because of the restart of the application with the update of appsettings, I feel like it is too much time for a user to wait. – Isuru Jun 17 '19 at 10:18
  • 1
    Hm usually this shouldn’t take minutes in my experience. Is your function rather big (many different functions in it)? You could try to carve out the schedule-updater into a completely separate Function – silent Jun 17 '19 at 10:21
  • Omg yes you have a point. I have 3 functions in the same place. Could that be a case then? – Isuru Jun 17 '19 at 10:23
  • 1
    Hard to tell from the outside. Generally three don’t sound like a lot. But as you updater function basically needs to restart itself. – silent Jun 17 '19 at 10:24
  • Thanks! I will make the scheduler function separate and see whether there is an improvement. – Isuru Jun 17 '19 at 10:27