Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure communication between Worker Role and Web Role

Hi I am building a Cloud Service which has (for the moment) one web and one worker role. My desired workflow would be: the browser calls a webApi controller on the web role, which sends a message to a queue (or service bus) which is then processed by the worker role. So far so good. Now when the worker role finishes processing the message I would like to call a method on the web role, who will then signal the browser that the processing has completed (via SignalR). Please excuse me if this is not the right place to ask since this is more like a “best practice” question rather that a real problem. I have so far considered 2 approaches:

  1. The worker role updates a table row (in the table storage) with the progress and the completion of the task. There is no signaling to the web role. The browser reads polls the table storage directly (via REST api) and therefore knows when the task has completed. This works well (I have already tested it), even though I don’t like the approach of constant polling and I would like to have an “event-based” solution. Moreover, once the client gets the info that the process has finished, it must perform an additional call to a web api method to broadcast to the other clients (via SignalR) that the operation was completed.

  2. Using Interrole communication together with SignalR (see code sample below) also works (already tested as well)

Code sample:

var protocol = "http";      
var ipAddress = RoleEnvironment.Roles["XXX.YYY.Web"]
        .Instances[0]
        .InstanceEndpoints.ToArray()
        .Where(ep => ep.Value.Protocol == protocol)
        .First()
        .Value.IPEndpoint.ToString();

var stringEndpoint = string.Format("{0}://{1}", protocol, ipAddress.ToString());                
Trace.WriteLine("Retrieved endpoint address: " + stringEndpoint, "Information");            
HubConnection connection = new HubConnection(stringEndpoint);
IHubProxy proxy = connection.CreateHubProxy("MyWebHub");
connection.Start().Wait();

//later...

proxy.Invoke("ProgressUpdated", clientId, progress);

My question is: are there other (better) ways to communicate in direction Worker role -> Web role? That is, trigger a method on the web role when a worker role has finished its processing? The method on the web role would then broadcast the update to all clients via SignalR. I have also taken a look at Event Hubs but to my understanding the Event Consumers would still run on the worker role.

like image 872
Mirko Lugano Avatar asked Apr 28 '15 09:04

Mirko Lugano


People also ask

What is the difference between web role and Worker role in Azure?

The only difference between the two is how your role is hosted on the VMs: Web role: Automatically deploys and hosts your app through IIS. Worker role: Does not use IIS, and runs your app standalone.

What are the 3 roles in Azure?

Account Administrator, Service Administrator, and Co-Administrator are the three classic subscription administrator roles in Azure.

What is web server role in Azure?

Web Role is a Cloud Service role in Azure that is configured and customized to run web applications developed on programming languages/technologies that are supported by Internet Information Services (IIS), such as ASP.NET, PHP, Windows Communication Foundation and Fast CGI.


1 Answers

Ok after some extra attempts and a bit of research I have come up with a possible solution... I was using this code

AzureServiceBus.QueueClient.OnMessage((message) =>
            {
                try
                {
                    // Process message from queue
                    Trace.WriteLine("Message received: " + ((BrokeredMessage)message).Label);

                    var breezeController = new BreezeController();
                    breezeController.TestSignal();

                    // Remove message from queue
                    message.Complete();
                }
                catch (Exception)
                {
                    // Indicates a problem, unlock message in queue
                    message.Abandon();
                }
            });

inside the OnStart method of the Web Role (NOT the Worker role) so that I could reference my method inside the web role (TestSignal() in this case) but it turned out that the IHubContext was always null when called from within this OnMessage event handler, since it belongs (very likely) to a different AppDomain thus even the static Hub of signalR was not shared. I have therefore moved this same whole code inside the Global.asax.cs so that it will share the same AppDomain and now it works. I think I will stay with this approach since I like it much more than the continuous polling.

like image 83
Mirko Lugano Avatar answered Sep 28 '22 13:09

Mirko Lugano