trace.writeline not working in azure Onstop method - azure

I am wondering why the following azure workerrole does not show any diagnostic messages when the role is shutdown:
public class WorkerRole : RoleEntryPoint {
private bool running=true;
public override void Run() {
while (running)
{
Thread.Sleep(10000);
TTrace.WriteLine("working", "Information");
}
Trace.WriteLine("stopped", "Information");
}
public override bool OnStart()
{
Trace.WriteLine("starting", "Information");
return base.OnStart();
}
public override void OnStop() {
Trace.WriteLine("stopping", "Information");
running = false;
base.OnStop();
}
}
I can see the events 'starting' and 'working' in the diagnostic logs, but the Onstop method does not log anything. I was wondering if it's even called so I injected some code in the OnStop() method to write out some data. In fact the data was written as expected which proves that the method is called, it's just that I don't get any logs. Any ideas how to Trace my shutdown code?

My first and best guess is that the Diagnostics Agent does not have time to transfer the trace out to storage for you to see it. Traces are first logged locally on the VM, then the agent will transfer them off (OnDemand or Scheduled) depending on how you have configured it. Once the VM shuts down, the agent is gone too and cannot transfer it off.

Tracing in OnStop is not supported and if you manage to get it working via On-Demand Transfer (http://msdn.microsoft.com/en-us/library/windowsazure/gg433075.aspx ) it's likely to not work in the next release. Note, tracing in Web Role OnStart does not work either. See my blog post http://blogs.msdn.com/b/rickandy/archive/2012/12/21/optimal-azure-restarts.aspx to fix that. Also see my blog post for instructions on view real time OnStop trace data with DbgView.
The OnStop method should be used only to delay shutdown until you've cleaned up - so you shouldn't have much code in there to trace. Again, see my blog for details.

Related

Why are my Azure triggered WebJobs never run successfully?

I have a few Azure WebJobs that run to completion, once my business logic is done I call await StopAsync(stoppingToken);
However, Azure Portal continues to show their status as "Running" until eventually the jobs terminated after the default 120 second timeout.
How can I correctly tell Azure Portal/Kudu that the job is in fact finished?
Here is an example that shows the issue:
namespace MyService
{
public class MyService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// same issue whether or not I call this:
await StopAsync(stoppingToken);
}
}
}
A week after posting this question my jobs are now mysteriously completing successfully even though no changes were made, I assume someone at Microsoft fixed something on their end.

No job functions found in Azure Webjobs

Trying to get Azure Webjobs to react to incoming Service Bus event, Im running this by hitting F5. Im getting the error at startup.
No job functions found. Try making your job classes and methods
public. If you're using binding extensions (e.g. ServiceBus, Timers,
etc.) make sure you've called the registration method for the
extension(s) in your startup code (e.g. config.UseServiceBus(),
config.UseTimers(), etc.).
My functions-class look like this:
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([ServiceBusTrigger("test-from-dynamics-queue")] BrokeredMessage message, TextWriter log)
{
log.WriteLine(message);
}
}
I have every class and method set to public
I am calling config.UseServiceBus(); in my program.cs file
Im using Microsoft.Azure.WebJobs v 1.1.2
((Im not entirely sure I have written the correct AzureWebJobsDashboard- and AzureWebJobsStorage-connectionstrings, I took them from my only Azure storage-settings in Azure portal. If that might be the problem, where should I get them ))
According to your mentioned error, it seems that you miss parameter config for ininitializing JobHost. If it is that case, please use the following code.
JobHost host = new JobHost(config)
More detail info about how to use Azure Service Bus with the WebJobs SDK please refer to the document.The following is the sample code from document.
public class Program
{
public static void Main()
{
JobHostConfiguration config = new JobHostConfiguration();
config.UseServiceBus();
JobHost host = new JobHost(config);
host.RunAndBlock();
}
}

Invoking a simple worker role

I'm trying to gain some understanding and experience in creating background processes on Azure.
I've created a simple console app and converted it to Azure Worker Role. How do I invoke it? I tried to use Azure Scheduler but looks like the scheduler can only invoke a worker role through message queues or HTTP/HTTPS.
I never thought about any type of communication as my idea was to create a background process that does not really communicate with any other app. Do I need to convert the worker role to a web role and invoke it using Azure Scheduler using HTTP/HTTPS?
Worker role has three events:
OnStart
OnRun
OnStop
public class WorkerRole : RoleEntryPoint
{
ManualResetEvent CompletedEvent = new ManualResetEvent(false);
public override void Run()
{
//Your background processing code
CompletedEvent.WaitOne();
}
public override bool OnStart()
{
return base.OnStart();
}
public override void OnStop()
{
CompletedEvent.Set();
base.OnStop();
}
}
The moment you run/debug your console converted worker role. First two (OnStart & OnRun) fires in sequence. Now in OnRun you have to keep the thread alive, either by using a while loop or using ManualResetEvent this is where your background processing code would live.
OnStop is fired when you either release the thread from OnRun or something un-expected goes. This is the place to dispose your objects. Close unclosed file-handles database connection etc.

Changes to Azure ServiceConfiguration.Cloud.cscfg file

What are the sequence of events that occur when I make changes to the settings file (ServiceConfiguration.Cloud.cscfg) for an cloud deployed App? Will the worker roles restart so that the new changes are reflected? (Will the OnStop, OnStart, Run events be trigerred on changing the settings value?)
In my cloud service, I read the custom values from the configuration file in the Run() method of the WorkerRole and wondering if any change to ServiceConfiguration.Cloud.cscfg file for an app deployed in the cloud will re-trigger the OnStart and Run events?
Yes indeed, your instances will go through OnStop / (Reboot) / OnStart / Run after each configuration change. If you're storing the settings in your application in a static variable for example it might be a good thing to let this happen. This way, after the reboot your application will restart and it will get a chance to re-initialize all settings in the static variables.
Now on the other hand, if you want the instance to reboot you can handle this change yourself (maybe you cached the settings somewhere, or iniitalized a static object without those settings). You'll need to trigger the reboot by handling the RoleEnvironment.Changing event :
public override bool OnStart()
{
RoleEnvironment.Changing += RoleEnvironmentChanging;
return base.OnStart();
}
private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
if ((e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)))
{
e.Cancel = true;
}
}

CloudQueueClient.ResponseReceived Event broken?

I'm trying to build an event driven Azure Queue where a event is to fired every time a message is put in the Azure Queue. With AzureXplorer I see that the messages are put in the Azure Queue properly but the CloudQueueClient.ResponseReceived Event never fires. I'm using Azure V1.4. This is the code from my Worker role:
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
while (true)
{
Thread.Sleep(10000);
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
var queuDataSource = new AzureQueueDataSource();
queuDataSource.GetCloudQueueClient().ResponseReceived +=new EventHandler<ResponseReceivedEventArgs>(WorkerRole_ResponseReceived);
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
return base.OnStart();
}
void WorkerRole_ResponseReceived(object sender, ResponseReceivedEventArgs e)
{
var i = 1; // Breakpoint here never happends
}
}
Windows Azure Queues need to be polled for new messages. See SDK samples or code here for examples on how to query queues for new messages.
Quick list of things to take into account:
Because polling is counted as a
transaction in Windows Azure, you
will be paying for those.
It is usually better to implement some kind of retry mechanism if no messages are found (e.g. exponential back-off, etc)
It is usually good to retrieve messages in batches (less round trips, less transactions, etc)
Remember that messages can be delivered more than once (plan for duplicate messages)
Use the "dequeuecount" property to deal with "poison messages".
There's plenty of coverage on all these. See the documentation/samples in the link above. This article is pretty good too: http://blogs.msdn.com/b/appfabriccat/archive/2010/12/20/best-practices-for-maximizing-scalability-and-cost-effectiveness-of-queue-based-messaging-solutions-on-windows-azure.aspx

Resources