Getting started with Background Workers: Error Handling and Output Capturing
Last month we launched the Background Workers beta. If you're unfamiliar with background workers, they're very easy to get started with. Any .exe files included in your project's build output will be run at each deploy. As one of the most frequently-requested features, we've already seen many of our customers take advantage of this new feature.
Background Workers are simple to write and deploy because there's nothing special about them; they're just regular .NET console apps. This gives you a lot of flexibility in the types of workers you can write. You can do one-time processing, scheduled tasks or handle long-running tasks like processing items from a queue.
In this post we'll cover some of the basics of writing your first background worker.
One-time processing
Many apps require tasks to be run the first time they are run. For instance you might need to populate a database with fresh data in a staging environment or update a CDN with the latest version of your site's static assets. To run a one-time task like this with an AppHarbor Background Worker, add a new Console project to your solution. Here's a basic example of a worker that's not very useful:
namespace WorkerDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("AppHarbor background workers rock!");
// do something useful :)
}
}
}
The next time you deploy your app your worker will be executed. If it completes without an error, it won't be run again until your next deploy. If there's an error during execution, the worker will be restarted.
Error Handling and Capturing Output
Current we do not provide logs of the console output generated from background workers. We're working on adding this feature in the future, but for now you'll need to log your own errors. The best way to do this is to wrap your entire worker in a try/catch block and grab the exception details to store or notify someone that something went wrong. Below, we'll see how this could be accomplished using NLog and the Logentries add-on.
Capturing exceptions is useful, but we can take things a step further and capture the output of all Console.Write
and Console.WriteLine
calls. We've written a helper class that captures the console output written by those two methods and stores it for you to access later. You can find the code for the ConsoleMirror utility on our GitHub page. As a bonus, our ConsoleMirror class not only captures the output, but still sends it to the console so that when you run your worker locally you can still see what's happening.
To get started, install the ConsoleMirror NuGet package to add it to your project. To wire it up, add the following lines to your app:
using AppHarbor;
namespace WorkerDemo
{
class Program
{
static void Main(string[] args)
{
ConsoleMirror.Initialize();
try
{
Console.WriteLine("AppHarbor background workers rock!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
var output = ConsoleMirror.Captured;
// do something useful with the output
}
}
}
Doing Something Useful with the Captured Output
Now that we have a copy of the output from our worker we could email it (using the Sendgrid or Mailgun add-ons, of course) or log it. Using the Logentries add-on with NLog, we can store the console output like this:
using System;
using AppHarbor;
using NLog;
namespace WorkerDemo
{
class Program
{
private static Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
ConsoleMirror.Initialize();
try
{
Console.WriteLine("AppHarbor background workers rock!");
logger.Info(ConsoleMirror.Captured);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
logger.Error(ConsoleMirror.Captured);
}
}
}
}
The Logentries web interface will now include a history of what our worker produced while running.
More on Background Workers
In a future posts we'll cover how to write long-running workers and how to use background workers to run tasks on a schedule. In the meantime, we'd like to see what you've done with background workers in your apps. Send us an example we can include on our blog, or write about it on your own blog and we'll send some sweet AppHarbor swag your way.