How to read Cron Expression from appsettings.json in .Net core Web Jobs - .net-core

I have developed .Net Core 2.2 Azure Web Job project which is having multiple timer trigger functions. One function is run on every 15 minutes and other one is run on every 10 minutes.
public async Task GetRecordsFromCosmosDBCollection_0([TimerTrigger("0 0/15 * * * *")]TimerInfo timerInfo){
//Custom Business Logic
}
public async Task GetRecordsFromCosmosDBCollection_1([TimerTrigger("0 0/10 * * * *")]TimerInfo timerInfo){
//Custom Business Logic
}
If I used the CRON expression directly in the function parameters then it works as expected. But I want to read the CRON expression information from appsettings.json file and then pass it to the above two functions.
So, can anyone suggest the right approach of reading the CRON expression information from appsettings.json in Functions.cs file in Azure WebJob project.

I assume the motivation is to get the schedule out of the compiled code where it can be changed without having to re-compile and re-deploy.
This might not be the most elegant solution - but you could put your two functions into two different scheduled WebJobs. Then you could set a separate settings.job for each one.
https://learn.microsoft.com/en-us/azure/app-service/webjobs-create#CreateScheduledCRON
The external settings.job file is deployed to the folder where the WebJob exe is - typically D:\home\site\wwwroot\App_Data\jobs\triggered\WebJobName - and you could change the schedule there.
To have different schedules - you'd have to split into different WebJobs because the settings.job schedule is kicking off Main, as opposed to a specific function like [TimerTrigger].
In a scheduled job, the code in Main would look like this:
await host.StartAsync();
await jobHost.CallAsync("ManualTrigger", inputs);
await host.StopAsync();
where "ManualTrigger" is the function in Functions.cs. The schedule in settings.jobs kicks off Main, runs the function, and then shuts down.

Related

repeated firebase deploy functions pub/sub creates duplicate scheduler jobs

I use the following command to deploy my project, one of the functions being a pub/sub:
firebase deploy --only functions
...and everything happens just fine, but the scheduler job is created a 2nd time, an exact copy of the previous one every time I deploy again.
I don't change the pub/sub function, so I would not necessarily need to include it during deploy, but why is it creating a new scheduler job every time? Neither the function, nor the topic in Pub/Sub is duplicating, only the scheduler job - why?
Here is how the pubsub function looks like, if relevant:
export const scheduledStuff = functions.pubsub
.schedule('0 0 * * *')
.timeZone('America/New_York')
.onRun(() => {
// do stuff
})
Update Jun 17 2022: I didn't specifically mention this, but the code I gave above, I hoped, should have given it away: I'm using the ES6 annotation for the function, ie. use import instead of require for packages, and the function is exported as export const scheduledStuff... instead of exports.scheduledStuff....
My functions are then separated into 2 categories, functions:functions, which are all the functions that are NOT pubsub, and this one pubsub. This is because I wanted to prevent the deployment of the pubsub function to my staging environment, so I'm using firebase deploy --only functions:functions for that one.
For this purpose I have an index file in my main functions directory that looks something like this:
import { default as firstFunction } from './callables/firstFunction.js'
import { default as secondFunction } from './callables/secondFunction.js'
//...
export const functions = {
firstFunction,
secondFunction,
//...
}
import { scheduledStuff } from './pubsub/scheduledStuff.js'
export const pubSubStuff = { scheduledStuff }
I tried to reproduce your case by deploying the below scheduler function which will run every minute and create a pubsub topic and a scheduler job.
In my case, my first deploy firebase deploy –only functions created a pubsub topic firebase-schedule-scheduledFunctionCrontab-us-central1 and a scheduler job firebase-schedule-scheduledFunctionCrontab-us-central.
With the second deployment firebase deploy –only functions, neither a duplicate scheduler job was created nor a duplicate pubsub topic.
My terminal shows the below lines:
functions: updating Node.js 16 function scheduledFunctionCrontab(us-central1)...
✔ functions[scheduledFunctionCrontab(us-central1)] Successful update operation.
The last deployment run got updated but a duplicate is not created. Also the scheduler function keeps updating the last run time and next run time field which confirms that the function is running every minute.
If what you have shared here, is the entire code of your scheduler function, then I think this is a Customer issue/bug.
Still to confirm I would like to have a look at your logs, but if you are confident that this is not an intended behavior (which seems to be according to me) please raise a support ticket with Google Cloud Support or raise a Customer issue in a public issue tracker

How to deploy Firebase Cloud functions programmatically, to be run at a specific time?

Usually functions are deployed via CLI, calling the firebase deploy -only functions:my_function.
Is it possible to deploy functions programmatically (hence dynamically)?
In my use case I would like to re-schedule a PubSub to run after a specific amount of time, relative to the current execution time, rather than regularly every time interval.
The same way as setTimeout would work (rather than a setInterval), but without having a process running and waiting to call the function.
What would be the drawbacks?
What would be alternative ways to achieve a similar result with what Firebase provides?
You already deploy that Cloud Function programmatically by issuing a command.
Generally there's repeated and delayed execution available.
a) Cloud Scheduler crontab receives scheduled Pub/Sub events:
exports.cronjob = functions.pubsub.schedule('0 */12 * * *').onRun(async context => {
...
});
b) Cloud Tasks may be better to schedule at a specific time.

Simplest Way to Schedule Multiple Webjobs from DevOps

I have an app service in Azure running the front end from my MVC5 app, and another app service for web jobs. The app has several endpoints (GET Actions) which do some processing, send some emails or other simple task. Previously when we were hosted on a VPS, we used the Windows Task Scheduler to call each URL on a custom schedule. In Azure, the way we're currently doing this is with a Powershell script which uses CURL to fetch the URL and trigger the processing.
It seems messy though - as each powershell script has to be uploaded individually, and can't be viewed or changed after uploading. I've found various guides on deploying a .NET Core console app, but from what I can tell each job would need it's own project, deployed with it's own pipeline.
Is there a nicer way of doing this, are Webjobs even the right tool for this job, given the seemingly simple task we're performing.
As far as I understand your use case, you can use Azure Function App Timer Trigger to accomplish it.
A timer trigger lets you run a function on a schedule.
The following example shows a C# function that is executed each time the minutes have a value divisible by five (eg if the function starts at 18:57:00, the next performance will be at 19:00:00). The TimerInfo object is passed into the function.
[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
if (myTimer.IsPastDue)
{
log.LogInformation("Timer is running late!");
}
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
The attribute's constructor takes a CRON expression or a TimeSpan. You can use TimeSpan only if the function app is running on an App Service plan. TimeSpan is not supported for Consumption or Elastic Premium Functions.
CRON (NCRONTAB expressions)

For Hangfire, is there any sample code for non-simple tasks; and how should recurring tasks be handled when re-publishing?

I am considering using Hangfire https://www.hangfire.io to replace an older home-grown scheduling ASP.NET web site/app.
I have created a simple test project using Hangfire. I am able to start the project with Hangfire, submit (in code) a couple of very simple single and recurring tasks, view the dashboard, etc.
I'm looking for more suggestions for creating a little more complex code (and classes) for tasks to be scheduled, and I have a question about what happens with permanently scheduled tasks when re-publishing a Hangfire site to production.
I have read some of the documentation on the Hangfire site, reviewed the 2 tutorials, scanned the Hangfire forums, and searched StackOverflow and the web a bit. A lot of what I have seen shows you how to schedule something very simple (like Console.WriteLine), but nothing more complex. The "Highlighter" tutorial was useful, but that essentially shows how to schedule a single instance of a (slightly longer-running) task in response to an interactive user input. I understand how useful that can be, but I'm more interested in recurring tasks that are submitted and then run every day (or every hour, etc.) and don't need to be submitted again. These tasks could be for something like sending a batch of emails to users each night, batch processing some data, importing a nightly feed of external data, periodically calling a web service to perform some processing, etc.
Is there any sample code available that shows some examples like this, or any guidance on the most appropriate approach for structuring such code in an interface and class(es)?
Secondly, in my case, most of the tasks would be "permanent" (always existing as a recurring task). If I set up code to add these as recurring tasks shortly after starting the Hangfire application in production, how should I handle it when publishing updates to production (when this same initialization would run again)? Should I just call "AddOrUpdate" with the same ID and Hangfire will take care of it? Should I first call "RemoveIfExists" and then add the recurring task again? Is there some other approach that should be used?
One example would be a log janitor, which would run every weekday # 5:00PM to remove logs that are older than 5 days.
public void Schedule()
{
RecurringJob.AddOrUpdate<LogJanitor>(
"Janitor - Old Logs",
j => j.OnSchedule(null),
"0 17 * * 1,2,3,4,5",
TimeZoneInfo.FindSystemTimeZoneById("CST"));
}
Then we would handle it this way
public void OnSchedule(
PerformContext context)
{
DateTime timeStamp = DateTime.Today.AddDays(-5);
_logRepo.FindAndDelete(from: DateTime.MinValue, to: timeStamp);
}
These two methods are declared inside LogJanitor class. When our application starts, we get an instance of this class then call Schedule().

a service which would be able to run jobs on a timed basis

I am working for my client using Asp.net webAPI2 and angularJS. Now my client have following requirement,but i am unable to understand what type of project i have to create like WebAPI project,window service or any other? Anyone please tell me what the client actually want and how can i do it?
QueueManager will need to be some kind of a service which would be able to run jobs on a timed basis. We envision it being a service that runs on a continuous loop, but has a Thread.Sleep at the end of each iteration with a duration of x-seconds (“x” being set in a config file.) You should create this QueueManager service as a new project within the Core.Jobs project; I would like to have the project name be “Core.Jobs.QueueManager”, along with the base namespace.
Here are the functions that the QueueManager will do for each iteration:
1) Do a worker healthcheck (JobsAPI: Queue/WorkerHealthCheck – already created)
a. This method will just return a 200 status code, and a count of workers. Not need to act on the return value.
Look at Hangfire, it is quite easy to set up and simple to use.
http://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html

Resources