Azure worker role as a service

Premise

Hello rock stars, ready to try something crazy? Ok, here you go. We know that Azure worker roles are meant to perform long running, background tasks. E.g. the most popular implementation pattern is that the frontend website/service accepts the requests and then worker role that is running in a separate process goes through the requests in an asynchronous fashion. Very powerful approach, especially since you can just scale-out and yank though millions of requests coming in. 

One important point to note here though is – worker roles do not have IIS. They can have endpoints, but they do not have IIS (or hosted web core for that matter). This means- though you can have endpoints but you can not really have IIS hosted services in the worker roles. You need to self host them.

Another angle that bothers many is worker role’s testability. As far as testing worker role as a white-box, you can just use the worker role dll/code and use hooks and mocks to test it as a unit. But there is a no real easy story to test worker role as the black box from outside.

Breaking Shackles

Here I am making a proposition to host the worker role code as a service, which then can be invoked from outside in a request-response manner. Again, this is little crazy, out-of-the-box approach so weigh it carefully and use it if it fits your bill.

Defining input endpoint

Azure worker roles can have internal or input endpoints. To make it simple – input endpoints are exposed externally while internal endpoints are not. More about internal and inputs endpoints for some other post (or you can Google for it). In this scenario – since we want to expose the worker role code to be invoked from outside we are going with an input endpoint.

As you can see below a new input http endpoint has been created which would use the port 80.

image

Self hosting service

Now that we have an endpoint, we can host the service using it. Going back to the worker role phenomenon we discussed above – worker roles do not contain IIS. So we need to host this http service without IIS. While I was thinking about it (and believe me there are many ways of doing it), the cleanest approach that came across was to use OWIN or what we refer to as Katana in the Microsoft world. Katana is probably the simplest, light-weight way to self-host a http service. Again, I am not going in much of Katana details here.

Go ahead and pull these nuget packages in your worker role project

As you can see in the code snippet below – we are using the endpoint (Name : Endpoint1) that we created in the above step. Best place to write code to self-host the service is in worker role’s OnStart() method that gets executed as the first thing after the deployment. We are hosting a basic ASP.NET Web API style REST service using Katana.

public class WorkerRole : RoleEntryPoint { public override bool OnStart() { var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"]; var baseUri = String.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint); WebApp.Start<KatanaStartup>(new StartOptions(baseUri)); return base.OnStart(); } } public class KatanaStartup { public void Configuration(IAppBuilder app) { var conifiguration = new HttpConfiguration();  

conifiguration.Routes.MapHttpRoute("Default", "{controller}/{id}",

new { id = RouteParameter.Optional }); app.UseWebApi(conifiguration); } }

Once the service is hosted, it’s just matter matter of defining the controller that matches the URI template defined in the service host. Here is how my basic controller looks like:

///

/// Actual Worker Role code that's getting called in WorkerRole Run() /// public class Processor { public bool Process(int value) { return true; } } /// /// Service controller implementation that invokes actual worker role code /// public class ProcessorController : ApiController { public HttpResponseMessage Get() { try { var flag = new Processor().Process(12); } catch (Exception ex) { return new HttpResponseMessage() { Content = new StringContent(ex.Message + ex.StackTrace) }; } return new HttpResponseMessage() { Content = new StringContent("Success!") }; } } }

As shown in the above code snippet – Processor class encapsulates actual worker role logic that gets executed every time worker role’s Run() method is called. ProcessorController (forgive me about naming it ProcessorController 🙂 ) is the class that gets instantiated and invoked by the OWIN hosted service. This class is nothing but a pass-through piece that ultimately invokes the actual worker role code. Here I have shown a basic Get implementation where in exception cases we are responding with exception details and a dummy string in case of success. You are encouraged to be creative and implement the best REST service patterns and practices or pass parameters using the Post implementation.

Using service for testing

Go ahead and host it in Azure or in the local emulator. Try accessing using:

Now that the service is hosted, it can be invoked from outside to perform the black box testing as we were planning.

PS : Here I haven’t given much thought to the endpoint security. I know it is pristine important, but that’s not the focus of this post.    

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s