Running multiple workers inside one Windows Azure Worker Role

Even the smallest Azure Worker Role, the Extra Small Instance, can be too large. At least too large for running just one piece of work on it. I’m currently running a couple small processes on one worker role and even now, the amount of CPU usage is below 1%. Yes you’re reading this correctly, I’m running multiple small processes on one worker role, and I’m planning to add more. I’m only using a small percentage of the resources on the worker role, so why should I add a worker role for every small process? I think we should be careful in answering this question, because there could be reasons enough, why you want to separate things. One reason could be that you never want any influence of one process on the other. This is something that’s unavoidable when running multiple processes on one worker role, but still not every process has such requirements.

Let’s start with my influence for the solution I’m currently using. It all started with this article: Running Multiple Threads on Windows Azure. It’s an excellent article, and that solution works really well. Until you start making use of async/await. Because their solution is based on threads that are monitored it’s hard or even impossible to make this work with async/await. Still this article was of great help, without it my solution would not have been possible.

First of all it’s important to know that I’m not going to paste all of the code in this blog post. I’m just going to explain the important bits, and the full solution can be downloaded for you to experiment with.

When you’re looking for a solution to run a Worker Role inside a Web Role you should definitely take a look at the solution Marcel Meijer created.

Independent workers

Let’s start with the easy part, the independent workers. You can have one, two, or ten. It doesn’t really matter that much to the solution, though you should monitor of course of your production Worker Role can handle all the load.

There’s a Start method and a Run method, and yes, there’s no Stop method. The stopping is done through a CancellationToken that’s signaled. You know best when you’re able to stop your worker, not in the middle of sequence of steps of course, so you should check if the CancellationToken is set at the place you think is the best place in your workers code. I’m usually checking at the beginning and the end of a sequence.

public class ExampleWorker1 : WorkerEntryPoint
{
    protected CancellationToken CancellationToken { get; set; }

    public override async Task<bool> OnStart(CancellationToken cancellationToken)
    {
        CancellationToken = cancellationToken;
        return await Task.FromResult(true);
    }

    public override async Task Run()
    {
        try
        {
            while (true)
            {
                ContinueOrCancel();
                Trace.TraceInformation("ExampleWorker1:Run");
                ContinueOrCancel();
                const int sleepTime = 5*1000;
                await Task.Delay(sleepTime);
            }
        }
        catch (OperationCanceledException)
        {
            Trace.TraceInformation("ExampleWorker1:Cancelled by cancellation token.");
        }
        catch (SystemException)
        {
            throw;
        }
        catch (Exception ex)
        {
            Trace.TraceError("ExampleWorker1:Run Exception", ex.ToString());
        }
    }

    private void ContinueOrCancel()
    {
        if (CancellationToken.IsCancellationRequested)
            CancellationToken.ThrowIfCancellationRequested();
    }
}

 

You can create multiple workers like the one above. To get started use the above template and implement your own logic at the highlighted line.

A very simple worker role

Of course you want to combine the multiple workers in the worker role. That’s easy, in the below example I’m just including 2 workers, but there could be more. You can even put multiple instances of the same type of worker in the list, as long as the workers support running simultaneously.

public class WorkerRole : TasksRoleEntryPoint
{
    public override void Run()
    {
        var workers = new List<WorkerEntryPoint>
                            {
                                new ExampleWorker1(),
                                new ExampleWorker2(),
                            };

        Run(workers.ToArray());
    }
}

Behind the scenes of the TasksRoleEntryPoint

All the magic is happening in the TasksRoleEntryPoint. When a worker is ended, outside of a cancellation, it will be automatically restarted.

/// <summary>
///     Called from WorkerRole, bringing in workers to add to tasks
/// </summary>
/// <param name="arrayWorkers">WorkerEntryPoint[] arrayWorkers</param>
public async void Run(WorkerEntryPoint[] arrayWorkers)
{
    try
    {
        _workers = arrayWorkers;

        foreach (WorkerEntryPoint worker in _workers)
        {
            await worker.OnStart(_tokenSource.Token);
        }

        foreach (WorkerEntryPoint worker in _workers)
        {
            _tasks.Add(worker.ProtectedRun());
        }

        int completedTaskIndex;
        while ((completedTaskIndex = Task.WaitAny(_tasks.ToArray())) != -1 && _tasks.Count > 0)
        {
            _tasks.RemoveAt(completedTaskIndex);
            //Not cancelled so rerun the worker
            if (!_tokenSource.Token.IsCancellationRequested)
            {
                _tasks.Insert(completedTaskIndex, _workers[completedTaskIndex].ProtectedRun());
                await Task.Delay(1000);
            }
        }
    }
    catch (Exception e)
    {
        Trace.TraceError(e.Message);
    }
}

 

And when the OnStop is called on the WorkerRole, it will fire Cancel on the CancelTokenSource and wait for all tasks to stop nicely.

public override void OnStop()
{
    try
    {
        _tokenSource.Cancel();
        Task.WaitAll(_tasks.ToArray());
    }
    catch (Exception e)
    {
        Trace.TraceError(e.Message);
    }
    base.OnStop();
}

 

Complete source

Because pasting all the code in this blogpost doesn’t make too much sense, I created a fully downloadable source-package. Hope this helps others as much as it helped me.

State of Silverlight on my Blog - Edition 2013

Alright, I’ve been blogging about this before, but Silverlight support is no longer increasing. At least when I’m looking at the stats of my blog. The last couple of years the amount of users on my blog that had support for Silverlight was increasing. Though it isn’t anymore it seems.

Important: I’m comparing the stats I have on my blog, this is of course not comparable with the web, nor a statement on Silverlight in general!

silverlight-stats

 

I’ve been comparing the visitors who have support for any version of Silverlight, this percentage is lower in 2012 than it was in 2011. I think that this is something we could have been expecting, because there are no mobile devices, phone and tablet, that support Silverlight in their browser. Tablets are becoming more and more common these days, so more of the visitors will use tablets to visit my blog.

For me, my conclusion is to get rid of the Silverlight Tag Rotator on my page, never saw it? You’re probably running without Silverlight.

Improve the usability of search in your Windows Style App

When your app could do with the search feature, implement it. But something that’s even more important is the discoverability of search. Not everyone knows how use the charms bar, or doesn’t want to use the charms. When you just start typing in the Store app it starts immediately showing the search pane with the input characters. I suggest you do the same when your apps supports search. How?

One line of code in your App OnLaunched method, I added it just after Window.Current.Activate().

// Show search on keyboard input.
SearchPane.GetForCurrentView().ShowOnKeyboardInput = true;

 

I know this is a very short post, but the API was pretty unknown to me until I tried it myself.

Update 23-01-2013:

Chris Veeningen (@Bloodyairtimer) explained to me that this should only be used on read-only views. So if you instead have an input box in your view this won’t work. So instead you could put the above line of code in the OnNavigatedTo method of your readonly views. I would also set it to false in the OnNavigateTo method of the views that contains input fields. Hope this helps a bit.

Searching a database solution for Windows Phone 7-8 and for Windows 8

I’m preparing for one of my new app-ideas. This app-idea requires a local storage of data, initially I want to create this app for Windows Phone, but I would like to have as much code-reuse as possible. So it would be very nice to have the same database solution for all platforms.

I’ve been using Sterling in the past for Windows Phone. This was before SQL CE was available for Windows Phone. Looking at releases, the last release of Sterling is from June 2011, more than a year and half ago. When I’m looking at the Source Code I’m seeing an resume in commits in last December. So the project is not dead, at least it doesn’t look dead to me. There’s also a discussion on the Future of Sterling which might interest you. There seems to be an issue with Windows Phone 8 which you can easily patch yourself. Okay, interesting, but there is no solution for Windows 8 apps yet.

Let’s explore the other options. SQL CE was added to Windows Phone 7 during one of the updates. However it’s not added to Windows 8 and will probably not be added to Windows 8 because there has been a lot of talking about SQLite in the area of Windows 8. But for Windows Phone 8 SQL CE seems to be lacking and there’s an option to use SQLite for Windows Phone 8 as well. So definitely no SQL CE for me, I want to have a solution that works at least for the whole Phone platform and not just the Windows Phone 7 platform.

So there’s a lot of talking about SQLite? It does support Windows 8 and Windows Phone 8 apps. After some searching there isn’t any official support for Windows Phone 7. I found an article written in 2011 that might help get SQLite on Windows Phone 7. This is an almost solution, maybe I just need to give SQLite a try.

While browsing the Sterling discussions I came around a comment about Lex.DB. This might be an interesting alternative, but it doesn’t support Windows Phone 7 yet. I’ll keep an eye on this project, but it’s very new in this space.

Update 26-01-2013:

In the comments Marcio already says that SQL CE works fine on Windows Phone 8. So even while there isn’t much to be found on that subject it should work. I had to try this myself, so I did. And the end-result? Windows Phone 8 supports SQL CE very well, nothing special that I’ve found in there so far.

Google Analytics now also on your Windows Phone 8 app in 1 minute

Yes today I released the Google Analytics NuGet package that supports Windows Phone 8. It’s part of the same NuGet package of the version for Windows Phone 7. I’ve heard that creating an app account doesn’t work any longer with Windows Phone apps, though you can fake it into a website. But for the detailed three steps I recommend reading my previous post. The fast track?

Open the NuGet Package Manager Console and type:

Install-Package MSAF.GoogleAnalytics
Have fun!