How to run Azure Web job using C# - c#

I created a web job (Console Application) on azure for copying one container blob to another and register on Azure.
It is working properly.
But I want to call the this from c# code not azure scheduler.
How is it possible ?
Like :-
if (Check == true)
{
//Run Web Job Code here
}

Add an "settings.job" file to the root of your job directory. This file must contain an Cron-Expression to start the job (basic cron syntax).
{
"schedule": "0 * * * * *"
}
runs for example, every hour.
For a more detailed description: https://github.com/projectkudu/kudu/wiki/Web-jobs

Related

Azure creates duplicate webjobs for Scheduled and Continuous

I have a scheduled web job created in Azure app service developed using C#. I want to change my web job from scheduled to continuous, but upon deploying the web job from visual studio it created a new instance of the web job in the Azure portal(1-Continuous and 1-Scheduled).
Duplicate Web Jobs in Azure Portal
webjob-publish-settings.json
Before:
{
"$schema": "http://schemastore.org/schemas/json/webjob-publish-settings.json",
"webJobName": "SampleWebJob",
"runMode": "OnDemand"
}
After:
{
"$schema": "http://schemastore.org/schemas/json/webjob-publish-settings.json",
"webJobName": "SampleWebJob",
"runMode": "Continuous"
}
I would like to overwrite the existing web job instead of creating a new one. Is there any way I can do it?
Also is there any way I can achieve this using ARM templates?
If the webjob is the same one, azure will overwrite it. And in your case actually it's the new webjob that's why it creates a new one.
If you only have one webjob and you want to change the type and don't want keep it after deployment, you could set Delete Existing Files to true.
If you have more than one webjob, you have to delete it on the portal or go to you web kudu site and delete it from the app_data folder.

Clearing history while debugging azure durable functions

Durable functions keep a state in storage, this is what makes them work, but it is very troublesome while debugging and developing. I have a large number of runs which have not completed and that the system tries to run again when I start the process. Some of the runs have erroneous data same which causes exceptions while others have been terminated early as something did not work as expected.
I don't want to run all the old cases when starting my application in debug (running against my local storage account). How can I automatically clear all data so only new functions will trigger?
You can use Azure Core Tools to purge the orchestration instance state.
First you need to make sure that the Azure Core Tools is installed for your particular Azure Function version. You can do this using the NPM package manager. (Note that this is for the Azure Functions Version - V3.)
npm install -g azure-functions-core-tools#3
Then open a command prompt in the root directory of your Azure Functions project. The Azure Core Tools requires the host.json file from your project to identify your orchestration instances.
You can use the following to look at all of the available actions:
func durable
You can then purge the instance history using the following:
func durable purge-history
There is now this VsCode extension, which now also has 'Purge Durable Functions History' feature. Type 'Purge Durable Functions History' in your Command Palette - and there you go. If you're not using VsCode, then the same tool is available as a standalone service, that you can either run locally or deploy into Azure.
You may call the PurgeInstanceHistoryAsync method with one of the following:
An orchestration instance ID
[FunctionName("PurgeInstanceHistory")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[ManualTrigger] string instanceId)
{
return client.PurgeInstanceHistoryAsync(instanceId);
}
Time interval
[FunctionName("PurgeInstanceHistory")]
public static Task Run(
[DurableClient] IDurableOrchestrationClient client,
[TimerTrigger("0 0 12 * * *")]TimerInfo myTimer)
{
return client.PurgeInstanceHistoryAsync(
DateTime.MinValue,
DateTime.UtcNow.AddDays(-30),
new List<OrchestrationStatus>
{
OrchestrationStatus.Completed
});
}
Reference for code snippets above: https://learn.microsoft.com/en-gb/azure/azure-functions/durable/durable-functions-instance-management#purge-instance-history
For everyone else wondering just how on earth to do this.
Install the Microsoft Azure Storage Explorer
Add a connection to azure storage, but choose Local storage emulator
4. Use the defaults / click next.
At this point, Click on Local & Attached in the Explorer. Click on (Emulator Default Ports) (Key) -> Tables. Delete the task hug history table, and relaunch your application.
From this point, its only a matter of dev time to figure out a way to do it programatically.

Azure function TimerTrigger only running once

This is my Function.Json
{ "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.28", "configurationSource": "attributes", "bindings": [
{
"type": "timerTrigger",
"schedule": "*/5 * * * * *",
"useMonitor": true,
"runOnStartup": false,
"name": "myTimer"
} ], "disabled": false, "scriptFile": "../bin/PullRequest.dll", "entryPoint": "PullRequest.PullRequest.Run" }
This is my actual function:
[FunctionName("PullRequest")]
public static void Run([TimerTrigger("*/5 * * * * *")]TimerInfo myTimer, ILogger log)
{
if (myTimer.IsPastDue)
{
log.LogInformation("Timer is running late!");
}
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
When I tried to run this function on Azure portal then it only run once and stops.
this is the log of the Azure Funciton:
I rerun it and now it only running once.:
Time trigger will automatically execute as per CORN expression i.e. in your case this function will execute every five seconds and If you run it from azure portal it will run only once.
If you want to check timings of last executions you can go to Monitor tab and check timings .
I have executed this locally and its working as expected
Like DavidG said: the Logs you're showing us, show that the function PullRequest ran at least 3 times.
Once where the executing log line isn't visible, so the reason is not clear
Once because the timer fired (#11:30:00)
Once because it was programmatically called via the host APIs (AKA manually)
Your CRON expression */5 * * * * * roughly translates into 'run this every time the number of seconds is divisible by 5'. That wouldn't match with the logs you're providing. Are you sure that's the CRON expression you're using?
Azure Functions uses the NCronTab library to interpret CRON expressions. A CRON expression includes six fields:
{second} {minute} {hour} {day} {month} {day-of-week}
Taken from Timer trigger for Azure Functions - CRON expressions.
EDIT:
Functions running on a Timer Trigger are automatically triggered on the specified timer intervals. To have the Functions actually run, you (of course) need to have something running that executes that trigger. Otherwise: how can they be triggered?
In Azure, the Functions Runtime is responsible for triggering the Function at the right time. Locally, the func.exe tool that starts automatically when you debug the application will do this for you. But if that doesn't run, nothing will happen.
Azure Functions Core Tools lets you develop and test your functions on your local computer from the command prompt or terminal. Your local functions can connect to live Azure services, and you can debug your functions on your local computer using the full Functions runtime.
and
To run a Functions project, run the Functions host. The host enables triggers for all functions in the project.
Taken from Work with Azure Functions Core Tools.
In short: "The host enables triggers. It needs to run to have something that triggers any Function".

Continuous Web Job with timer trigger and Blob trigger

I have the following functions in the same web job console app that uses the azure jobs sdk and its extensions. The timed trigger queries an API end point for a file, does some additional work on it and then saves the file to the blob named blahinput. Now the second method "ProcessBlobMessage" is supposed to identify the new blob file in the blahinput and do something with it.
public static void ProcessBlobMessage([BlobTrigger("blahinput/{name}")] TextReader input,
string name, [Blob("foooutput/{name}")] out string output)
{//do something }
public static void QueryAnAPIEndPointToGetFile([TimerTrigger("* */1 * * * *")] TimerInfo timerInfo) { // download a file and save it to blob named blah input}
The problem here is :
When I deploy the above said web job as continuous, only the timer triggered events seems to get triggered while the function that is supposed to identify the new file never gets triggered. Is it not possible to have two such triggers in the same web job?
From this article: How to use Azure blob storage with the WebJobs SDK
The WebJobs SDK scans log files to watch for new or changed blobs. This process is not real-time; a function might not get triggered until several minutes or longer after the blob is created. In addition, storage logs are created on a "best efforts" basis; there is no guarantee that all events will be captured. Under some conditions, logs might be missed. If the speed and reliability limitations of blob triggers are not acceptable for your application, the recommended method is to create a queue message when you create the blob, and use the QueueTrigger attribute instead of the BlobTrigger attribute on the function that processes the blob.
Until the new blob trigger strategy is released, BlobTriggers are not reliable. The trigger is based on Azure Storage Analytics logs which stores logs on a Best-Effort basis.
There is an ongoing Github issue about this and there is also a PR regarding a new Blob scanning strategy.
This being said, check if you are using the Latest Webjobs SDK version 1.1.1 because there was an issue on prior versions that could lead to problems on BlobTriggers.

Restart Azure Worker Role from Web Role

I have a Worker Role that executes code (fetching data and storing it to Azure SQL) every X hours. The timing is implemented using a Thread.Sleep in the while(true) loop in the Run method.
In the Web Role I want to have the abillity to manualy start the code in Worker Role (manualy fecth and store data in my case). I found out that the whole Worker Role can be restarted using the Azure Management API but it seems like an overkill, especialy looking at all the work needed around certificates.
Is there a better way to restart Worker Role from Web Role or have the code in Worker Role run on demand from the Web Role?
Anything like posting an event to an Azure Queue, posting a blob to Azure Blobs, changing a record in Azure Tables or even making some change in SQL Azure will work - the web role will do the change and the worker role will wait for that change. Perhaps Azure Queues would be the cleanest way, although I'm not sure.
One very important thing you should watch for is that if you decide to use polling - like query a blob until it appears - you should insert a delay between the queries, otherwise this code:
while( true ) {
if( storage.BlobExists( blobName ) ) {
break;
}
}
will rush into the storage and you'll encounter outrageous transaction fees. In case of SQL Azure you will not see any fees, but you'll waste the service capacity for no good and this will slow down other operations you queue to SQL Azure.
This is how is should be done:
while( true ) {
if( storage.BlobExists( blobName ) ) {
break;
}
// value should not be less that several hundred (milliseconds)
System.Threading.Thread.Sleep( 15 * 1000 );
}
Well I suggest you use Azure Fluent Management (which uses the Service Management API internally). Take a look at the "Deploying to Windows Azure" page.
What you will want to do is the following:
Cloud Service: mywebapp.cloudapp.net
Production slot
Role: MyMvcApplication
Cloud Service: mybackgroundworker.cloudapp.net
Production slot
No DEPLOYMENT
So you would typically have a Cloud Service running with a Web Role and that's it. What you do next is create the Worker Role, add your code, package it to a cspkg file and upload it to blob storage.
Finally you would have some code in your Web Role that can deploy (or remove) the Worker Role to that other Cloud Service by downloading the package locally and then running code similar to this:
var subscriptionManager = new SubscriptionManager(TestConstants.SubscriptionId);
var deploymentManager = subscriptionManager.GetDeploymentManager();
deploymentManager
.AddCertificateFromStore(Constants.Thumbprint)
.ForNewDeployment(TestConstants.HostedServiceName)
.SetCspkgEndpoint(#"C:\mypackage")
.WithNewHostedService("myelastatestservice")
.WithStorageAccount("account")
.AddDescription("my new service")
.AddLocation(LocationConstants.NorthEurope)
.GoHostedServiceDeployment();

Categories