question

Abhishek Agrawal avatar image
Abhishek Agrawal asked

Azure Functions not executing when running from a Scheduled Task

Hello, I am trying to run a azure functions from a scheduled task in the game, but when I run the function it gives an error "Object reference not set to an instance of an object."

However when I run the same azure functions from inside the player's profile in the dashboard it works without any issues.

I am confused as to why the azure function is giving error only when running on scheduled task.

I did some debugging to try and find the problem, and It seems its something with the HttpRequestMessage parameter in the function, But I can't understand exactly what is going wrong with it.

Here is the code snippet.

public static async Task<dynamic> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            log.LogCritical("TestStart");
            if(req == null){
                log.LogCritical("REQ is null");
            }
            log.LogCritical("Null Check");
            
            var reqStr = req.ToString();
            log.LogDebug("Check2");
            log.LogDebug("Request String :" + reqStr);

            var context = await FunctionContext<dynamic>.Create(req);
            var args = context.FunctionArgument;

            Settings.TrySetSecretKey(context.ApiSettings);
            Settings.TrySetCloudName(context.ApiSettings);
}

In the logs, when running from the dashboard from inside player profile it works, without any errors.

But when executed with the scheduled task it doesn't reach "Check2". Here is the logs in case of error :

[Information] Executing 'TestFunction' (Reason='This function was programmatically called via the host APIs.', Id=abc)
[Critical] TestStart
[Critical] Null Check
[Error] Executed 'TestFunction' (Failed, Id=abc, Duration=33ms)
Object reference not set to an instance of an object.

I did a lot of search about this issue, but could not find any case where the function did not execute on scheduled task when it does work when executing from the player info dashboard.

scheduled tasks
1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Abhishek Agrawal avatar image Abhishek Agrawal commented ·

I have also tried to change AuthorizationLevel from 'Function' to 'Anonymous' to check if that affects the HttpRequestMessage, But to no avail, its giving the same error, Still working from player dashboard but not when executed from a scheduled task.

0 Likes 0 ·

1 Answer

·
Citrus Yan avatar image
Citrus Yan answered

I tried you code snippet, and the HttpRequestMessage parameter won’t be a problem here. Most likely your code was running into issues when executing the following lines, because it’s using a wrong context model:

var context = await FunctionContext<dynamic>.Create(req);

var args = context.FunctionArgument;

You’re supposed to use the “ScheduledTaskFunctionExecutionContext” context model when executing via Scheduled Task, here is a sample code you may find helpful:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;


namespace PlayFab.Samples
{
    public static class CSAFForScheduledTask
    {
        [FunctionName("CSAFForScheduledTask")]
        public static async Task<object> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]  HttpRequest httpRequest,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");


            log.LogInformation($"Settings.TitleSecret: {Settings.TitleSecret}");


            string body = await httpRequest.ReadAsStringAsync();
            log.LogInformation($"HTTP POST Body: {body}");


            ScheduledTaskFunctionExecutionContext<object> ctx = JsonConvert.DeserializeObject<ScheduledTaskFunctionExecutionContext<object>>(body);
            log.LogInformation($"ScheduledTaskFunctionExecutionContext: {JsonConvert.SerializeObject(ctx)}");




            return await Task.FromResult(ctx.FunctionArgument);
        }
    }
}


2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Abhishek Agrawal avatar image Abhishek Agrawal commented ·

Thanks a lot! It fixed the problem.

I ended up using "PlayerPlayStreamFunctionExecutionContext" so I can get the player data as well.

Also for anyone looking at the issue in future, if you want to know details about the player who is calling this function, you can use "PlayerPlayStreamFunctionExecutionContext" context as well, it has the PlayerProfile in it, and works with Scheduled tasks.

Thank you again!

2 Likes 2 ·
Citrus Yan avatar image Citrus Yan Abhishek Agrawal commented ·

Glad that helped, happy coding:)

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.