Why is my webjob terminating without throwing an exception? - azure

My azure webjob appears to be terminating without throwing an exception and I'm lost.
My web job is run on-demand (or scheduled) and has a dependency on my web site DLL (and MVC app). It calls into it to do most of the work, which includes working with an entity frameworks database and making REST calls to several other sites. Most of the work is done asynchronously. Most of the code used to do this work is also called from other parts of the site without problem, and it goes without saying that the web job works flawlessly when run locally.
The web job terminates and doesn't seem to throw an exception when it does and it doesn't seem to be possible to debug a web that's not of the continuously run variety (?). Therefor, my debugging has mostly been of the Console.WriteLine variety. Because of that and the asynchronisity, I haven't been able to nail down exactly where it's crashing - I thought it was while accessing the database, but after mucking with it, the database access started working.. ugh. My next best guess it that it dies during an await or other async plumbing. It does, however, crash within two try/catch blocks that have finallys that log results to redis and azure storage. None of that happens. I can not figure out, or imagine, how this process is crashing without hitting any exception handlers.. ?
Anyone had this problem with an azure webjob? Any idea what I should be looking for or any tips for debugging this?
Thanks!

I figured it out! One of the many things happening asynchronously was the creation of a certificate. I traced it down to this:
signedCert = new X509Certificate2(cert, "notasecret", X509KeyStorageFlags.Exportable);
This code works fine when called from my azure website or my tests, but kills the webjob process completely without throwing an exception! For example, the WriteLine in the exception handler below never gets called:
X509Certificate2 signedCert;
try
{
signedCert = new X509Certificate2(cert, "notasecret", X509KeyStorageFlags.Exportable);
}
catch (Exception ex)
{
// We never get here! Argh!
Console.WriteLine("Exception converting cert: " + ex);
throw;
}
Extremely time consuming and frustrating. Unlike the diagnosis, the fix is simple:
signedCert = new X509Certificate2(
cert,
"notasecret",
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);

Related

Azure function goes idle when running in Consumption Plan with ServiceBus Queue trigger

I have also asked this question in the MSDN Azure forums, but have not received any guidance as to why my function goes idle.
I have an Azure function running on a Consumption plan that goes idle (i.e. does not respond to new messages on the ServiceBus trigger queue) despite following the instructions outlined in this GitHub issue:
The configuration for the function is the following json:
{
"ConnectionStrings": {
"MyConnectionString": "Server=tcp:project.database.windows.net,1433;Database=myDB;User ID=user#project;Password=password;Encrypt=True;Connection Timeout=30;"
},
"Values": {
"serviceBusConnection": "Endpoint=sb://project.servicebus.windows.net/;SharedAccessKeyName=SharedAccessKeyName;SharedAccessKey=KEY_HERE",
}
}
And the function signature is:
public static void ProcessQueue([ServiceBusTrigger("queueName", AccessRights.Listen, Connection = "serviceBusConnection")] ...)
Based on the discussion in the GitHub issue, I believed that having either a serviceBusConnection entry OR an AzureWebJobServiceBus entry should be enough to ensure that the central listener triggers the function when a new message is added to the ServiceBusQueue, but that is proving to not be the case.
Can anyone clarify the difference between how those two settings are used, or notice anything else with the settings I provided that might be causing the function to not properly be triggered after a period of inactivity?
I suggest there are several possible causes for this behavior. I have several Azure subs and only one of them had issues with Storage/Service Bus-based triggers only popping up when app is not idle. So far I have observed that actions listed below will prevent triggers from working correctly:
Creating any Storage-based trigger, deleting (for any reason) the triggering object and re-creating it.
Corrupting azure function input parameters by deleting/altering associated objects without recompiling a function
Restarting functions app when one of the functions fails to compile/bind to trigger OR input parameter and hangs may cause same problems.
It has also been observed that using legacy Connection Strings setting for trigger binding will not work.
Clean deploy of an affected function app will most likely solve the problem if it was caused by any of the actions described above.
EDIT:
It looks like this is also caused by setting Authorization/Authentication on the functions app, but I have not yet figured out if it happens in general or when Auth has specific configuration. Tested on affected Azure sub by disabling auth at all - function going idle after 30-40 mins, queue trigger still initiates an execution, though with a delay as expected. I have found an old bug related to this, but it says issue resolved.

TransactionScope in azure webjobs

I have a webjob running in azure that is processing data sent to an event hub.
In the eventprocessor I want to save information to a SQL server. To make sure that everything is inserted correctly I want to use transactions.
When I run the code locally everything works perfect. But when running in Azure nothing happens, no error is thrown.
What I have read it should be possible to use TransactionScope. This example code below is not working.
using (TransactionScope scope = new TransactionScope())
{
dataImportDao.StartProcessingMessage(mappedMessage);
scope.Complete();
}
Any suggestions how to solve it or if I should go with a different approach is very appreciated.

Why does my continuous azure webjob run the function twice?

I have created my first azure webjob that runs continously;
I'm not so sure this is a code issue, but for the sake of completeness here is my code:
static void Main()
{
var host = new JobHost();
host.CallAsync(typeof(Functions).GetMethod("ProcessMethod"));
host.RunAndBlock();
}
And for the function:
[NoAutomaticTrigger]
public static async Task ProcessMethod(TextWriter log)
{
log.WriteLine(DateTime.UtcNow.ToShortTimeString() + ": Started");
while (true)
{
Task.Run(() => RunAllAsync(log));
await Task.Delay(TimeSpan.FromSeconds(60));
}
log.WriteLine(DateTime.UtcNow.ToShortTimeString() + "Shutting down..");
}
Note that the async task fires off a task of its own. This was to ensure they were started quite accurately with the same interval. The job itself is to download an url, parse and input some data in a db, but that shouldnt be relevant for the multiple instance issue I am experiencing.
My problem is that once this has been running for roughly 5 minutes a second ProcessMethod is called which makes me have two sessions simoultaniously doing the same thing. The second method says it is "started from Dashboard" even though I am 100% confident I did not click anything to start it off myself.
Anyone experienced anything like it?
Change the instance count to 1 from Scale tab of WebApp in Azure portal. By default it is set to 2 instances which is causing it to run two times.
I can't explain why it's getting called twice, but I think you'd be better served with a triggered job using a CRON schedule (https://azure.microsoft.com/en-us/documentation/articles/web-sites-create-web-jobs/#CreateScheduledCRON), instead of a Continuous WebJob.
Also, it doesn't seem like you are using the WebJobs SDK, so you can completely skip that. Your WebJob can be as simple as a Main that directly does the work. No JobHost, no async, and generally easier to get right.

Azure webjob - QueueTrigger stops triggering

I am running an azure webjobs SDK console application (continuous) with the recommended setup:
public static void ProcessQueueMessage([QueueTrigger("logqueue")] string logMessage, TextWriter logger)
The azure queue I am running against has ~6000 messages in it and I am running the web-job locally, as a console application.
The problem I'm having is that the processing randomly stops after processing between zero and ~30 messages. The console stays open, but no more console messages are displayed.
For example, it might just process 2 messages:
Executing: 'Functions.ProcessQueueMessage' - Reason: 'New queue message detected on 'QueueName'.'
Executed: 'Functions.ProcessQueueMessage' (Succeeded)
Executing: 'Functions.ProcessQueueMessage' - Reason: 'New queue message detected on 'QueueName'.'
Executed: 'Functions.ProcessQueueMessage' (Succeeded)
And then, nothing. There doesn't seem to be anything wrong with my internet connection and I can't trace the issues down to any particular messages.
Has anyone else had issues with this SDK?
Update:
I made sure that I was using the right versions of all of the dependencies by removing the nuget packages and then re-running install-package Microsoft.Axure.Webjobs. I am now using webjobs version 1.1.0 which has pulled in version 4.3 of azure storage.
As recommended by Matthew, I have pulled down the source code for azure webjobs to determine where the process is freezing up. Once the freez-up occurs, I pause execution and checked the running threads for what I believe is the culprit within Microsoft.Azure.WebJobs.Host.CompositeTraceWriter
protected virtual void InvokeTextWriter(TraceEvent traceEvent)
{
if (_innerTextWriter != null)
{
string message = traceEvent.Message;
if (!string.IsNullOrEmpty(message) &&
message.EndsWith("\r\n", StringComparison.OrdinalIgnoreCase))
{
// remove any terminating return+line feed, since we're
// calling WriteLine below
message = message.Substring(0, message.Length - 2);
}
_innerTextWriter.WriteLine(message);
if (traceEvent.Exception != null)
{
_innerTextWriter.WriteLine(traceEvent.Exception.ToDetails());
}
}
}
The line it freezes on is line 66 : _innerTextWriter.WriteLine(message);
_innerTextWriter is an instance of System.IO.TextWriter.SyncTextWriter
Is it possible there is some deadlock issue with this class or the way it is being used?
Some notes:
I am running in the debugger, so in this case I believe the textwriter is forwarding to the console internally
I have my batchsize set to 1 via config.Queues.BatchSize = 1;, not sure if that could matter
I'm currently working on setting up an environment on another computer so that I can see if it is reproducible somewhere other than this machine (surface book).
Update
The issue was me not understanding how the new windows 10 command prompt works. Any time you click on the command window, it goes into "select" mode which completely pauses execution of the process.
Basically: https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly?newreg=ece53f5584254346be68f85d1fd2f18d
You can tell it is in this state because it will prefix the window title with the word "Select":
You have to press enter or click again to get it going once again.
So, two final comments:
1) What an incredibly confusing and un-intuitive behavior for a command window!
2) I hope some admin will come take pity on the shame I have brought upon myself and my family by deleting this question.
To get rid of this strange behavior, you can disable QuickEdit mode:
Strange. When it is in this stuck state, can you try adding a new queue message to the queue and see if that triggers? Are you sure your function isn't hanging internally? What version of the SDK are you using? You might also try upgrading to v1.1.0 which we just released last week. If there are really a bunch of messages in the queue waiting to be processed, I can't think of anything that would cause this. The queue listener in the SDK should chug along, reading batches of messages in parallel and dispatching them to your function. Have you changed any of the JobHostConfiguration.Queues configuration knobs? You haven't force updated the version of the Azure SDK have you to something higher than the WebJobs SDK supports?
Another option if you can't figure this out might be to clone the SDK, build it and debug it locally. The repo is here. The main queue processing loop is here.

SoapHttpClientProtocol automatically retry after exception?

I am just curious about this. I am making a change in this project, that is using NetSuite web service, and sometimes it throws a SoapException at random, "Only one request may be made against a session at a time".
private NetSuiteService _service;
SessionResponse response = _service.login(passport); //if SoapException, retries??
Status status = response.status;
Reference.cs:
public partial class NetSuiteService :
System.Web.Services.Protocols.SoapHttpClientProtocol
My question is: If I am in debug mode, I trace this, and I hit F5, and it seems to automatically retry after exception is thrown (the code keeps running, with no try catch block implemented, no while loop) until successful (status.isSuccess == true). When I run it in release mode, as a windows service, the log shows it stops running after exception is thrown.
How is this possible? Is it better to catch this exception in a try catch block and retry?
NS Server refuses a request if its already processing one from the same user.
If you want to make sure that your request succeeds than you have to catch this exception and retry.
This was not the experience I had. We thought this related to netsuite sessions but turned out to be nothing to do with that at all and in fact was not even hitting netsuite (according to netsuite log)​​. Turned out we were trying to execute too many commands in a single request and it totally refused to send it to netsuite. Never seen this error before, may be it is a new thing with the new version!

Resources