Windows Azure Web Role - Where does RoleEnvrironment.Changing go? - azure

Since version 1.3 of the Azure SDK we have to set the configuration publisher within our web application (e.g. global.asax) and not webrole.cs. Is the same true for hooking up RoleEnvironment.Changed/Changing events?

It depends. Your web application runs in a different process than your WebRole.cs meaning you'll need to handle it in one of these (or both) depending on the use case.
An example: Let's assume you have a static property in your global.asax that holds an object. This object has been initialized with information coming from your service configuration. Then a few days later you modify this configuration in the portal (maybe a connection string). This will raise the RoleEnvironment.Changing event. In that case, you'll need to handle that event in the web application (global.asax) to re-initialize the static object with the new configuration information.
Note that a web application is not always active, it's only fired up after the first request (you can modify this though, but this is the default behavior). Meaning that in some cases you might not be able to handle the event in the web application because the process is not active. If handling the event is crucial for you, you should consider handling it in the WebRole.cs

Related

Execute something which takes 5 seconds (like email send) but return with response immediately?

Context
In an ASP.NET Core application I would like to execute an operation which takes say 5 seconds (like sending email). I do know async/await and its purpose in ASP.NET Core, however I do not want to wait the end of the operation, instead I would like to return back to the to the client immediately.
Issue
So it is kinda Fire and Forget either homebrew, either Hangfire's BackgroundJob.Enqueue<IEmailSender>(x => x.Send("hangfire#example.com"));
Suppose I have some more complex method with injected ILogger and other stuff and I would like to Fire and Forget that method. In the method there are error handling and logging.(note: not necessary with Hangfire, the issue is agnostic to how the background worker is implemented). My problem is that method will run completely out of context, probably nothing will work inside, no HttpContext (I mean HttpContextAccessor will give null etc) so no User, no Session etc.
Question
How to correctly solve say this particular email sending problem? No one wants wait with the response 5 seconds, and the same time no one wants to throw and email, and not even logging if the send operation returned with error...
How to correctly solve say this particular email sending problem?
This is a specific instance of the "run a background job from my web app" problem.
there is no universal solution
There is - or at least, a universal pattern; it's just that many developers try to avoid it because it's not easy.
I describe it pretty fully in my blog post series on the basic distributed architecture. I think one important thing to acknowledge is that since your background work (sending an email) is done outside of an HTTP request, it really should be done outside of your web app process. Once you accept that, the rest of the solution falls into place:
You need a durable storage queue for the work. Hangfire uses your database; I tend to prefer cloud queues like Azure Storage Queues.
This means you'll need to copy all the data over that you will need, since it needs to be serialized into that queue. The same restriction applies to Hangfire, it's just not obvious because Hangfire runs in the same web application process.
You need a background process to execute your work queue. I tend to prefer Azure Functions, but another common approach is to run an ASP.NET Core Worker Service as a Win32 service or Linux daemon. Hangfire has its own ad-hoc in-process thread. Running an ASP.NET Core hosted service in-process would also work, though that has some of the same drawbacks as Hangfire since it also runs in the web application process.
Finally, your work queue processor application has its own service injection, and you can code it to create a dependency scope per work queue item if desired.
IMO, this is a normal threshold that's reached as your web application "grows up". It's more complex than a simple web app: now you have a web app, a durable queue, and a background processor. So your deployment becomes more complex, you need to think about things like versioning your worker queue schema so you can upgrade without downtime (something Hangfire can't handle well), etc. And some devs really balk at this because it's more complex when "all" they want to do is send an email without waiting for it, but the fact is that this is the necessary step upwards when a baby web app becomes distributed.

Transactions in NServicebus using Azure Service Bus Transport

I have several message handlers in a particular endpoint that do their work against a SQL Azure database (at the moment still using a local SQL 2012 instance). I have a command handler that publishes 2 events, call them X and Y. In the same endpoint I have a subscriber to X and a subscriber to Y. Both of these subscribers are internally using the same data access component, call that Z. Dependency injection is configured on a per-call basis, not shared.
Component Z is using Entity Framework 6 under the curtains. The issue I am having is that just opening the database is throwing a SqlException and complaining about MSDTC escalations.
I have temporarily wrapped the handlers in a TransactionScope.Suppress and that has stopped the error but I believe I'm missing something more fundamental.
Is it a simple matter of configuring the endpoint to be non-transactional? I would have thought this would just work seeing as I've configured to use Azure Service Bus as the transport mechanism. If I do this will NServiceBus still retry if an exception is thrown within the message handler? (Up to the SLR limits -- not part of the question, I also understand the idempotency issues).
#Phil,
First, you shouldn't be using MSDTC with SQL Azure - it's not supported. The feature is suggested, but only under review. DTC is not supported on Azure. Alternatively, you could look into the following suggestion to use SqlTransaction approach.
Second, transport you're using has nothing to do with your data access. Since you're using Azure Service Bus, it will not be part of your handler code. Making handler a transactional is to force an atomic change or roll-back. Regardless of your handler, will retry. Challenge is that when handler/endpoint is not transactional, and within handler first write to DB succeeded and second failed, first write won't be reverted. As for Azure Service Bus as a transport, it's not transactional in its nature (ie no DTC).
Which version of NServiceBus.Azure are you on? Do you have a stack trace of the exception? Where does it come from?
We push the sends and publishes out of the scope of the receive transaction scope explicitly to prevent promotion to the DTC, so that the transaction is local to the sql, so I doubt that is what is happening here.
From you description it looks like you are using a different data access instance for each handler (per call container config) and you have multiple handlers on the same message. If both of these open a new connection to the SQL you would see promotion as well (even if it is the same server)
Could that be it? That it throws on the second open?

Is it possible to start/stop a service-activator at runtime?

I have a web application that interfaces with another application through a message queue. So, my web application has a service-actibator that is bound to an inbound message driven channel adapter; currently it is is always listening for messages on the queue.
However, there may be times where it is desiarable to turn that listening off without bouncing the application itself. For example, if the queue gets a backlog of messages and for whatever reason the web application that is listening for these messages begins to have performance issues and we want to isolate the application from the queue to help identify if that is the source of the performance problem or not.
The bottom line is we are trying to proactivey look for ways to help our support staff when needing to diagnose potential inter-system issues...without having to necessarily bounce the servers for a configuration change.
Then if it is determined that the interface to the external system should be turned back on then we would want to be able to re-start the service activator.
Is anything like this possible? Or is there an approach that I'm not thinking of that would allow this type of runtime start/stop capability?
Yes, it is possible.
All Endpoints in the Spring Integration implement org.springframework.context.SmartLifecycle.
From other side SI has a component for this purpose - Control Bus
So, it very simple:
<channel id="controlBusChannel"/>
<control-bus input-channel="controlBusChannel"/>
<service-activator input-channel="stopMyServiceActivatorChannel"
output-channel="controlBusChannel" expression="'#myServiceActivator.stop()'"/>
<service-activator id="myServiceActivator" input-channel="myInputChannel"
output-channel="myOutupChannel"/>

Multithread operations in WCF Service contract implementation

I've seen a project lately using a background worker to make some operations (get data from other web services) and throw the data using events to the client. This project is a WCF service and consume by an ASP.NET web site by another class library as WCF client role and throwing in turn events to the application. This all multithreaded series made me curious to examine. I've seen that this is a basicHttpBinding binding and the only behavior to the service is the UseSynchronizationContext=false where I found out that they added it after unexplained exception which is normal :)
Now I'm asking about the default ConcurrencyMode for the basicHttpBinding. Shouldn't they make it Reentrant or this is the default behavior?
Is this scenario will continue failing cause they already have an unexplained reference not set to an instance of an object if the WCF service is down from the client?
I believe using multithread operations in a WCF service consume by ASP.NET project which relies on IIS handling is bad cause the page could be sent to the client before the WCF service return data to the client class library and append these to the page.
Can you discuss the above and explain your thoughts?
Shouldn't be better when you need such an asynchronous programming style to inform WCF comsumers to notify after long operation using CallbackContracts and embedded WCF technologies, rather multithreading operations?
Need clarification to correct the design and have some proves that this is a bad service architecture, if it is for real, which I suspect!
Thank you.
It is not inherently bad architecture, but it sounds like it does create a number of possible pitfalls.
The WCF client library is leaving all the coordination up to the ASP.NET application. If the ASP.NET app isn't checking that a call to the WCF service has been completed, then it risks using variables before they have been set with values from the service, and other such race conditions unless explicitly setting up some manner of coordinating the initial call against the completion events.
My recommendation would be to rewrite the WCF client asynchronous methods to return Task objects, from the System.Threading.Tasks namespace (MSDN reference). In this way you can spin off the background processing calling the WCF service, and use the Result property of the Task to ensure the service has completed.
An example:
protected void Page_Load(object sender, EventArgs e)
{
Task<string> t = Task<string>.Factory.StartNew(() =>
{
return MyWcfClientClass.StaticAsyncMethod(MyArguments);
}
/* other control initialization stuff here, while the task
and WCF call continue processing in background */
/* Calling Result causes the thread to wait for the task to
complete as necessary, to ensure we have our correct value */
MyLabel1.Text = t.Result;
}

How does Azure check the WorkerRole's status?

I see how Azure checks the status of my worker role periodically, but how?
There is no method in RoleEntryPoint to do that, and I'm taking a look on Microsoft.WindowsAzure.ServiceRuntime's classes with ILSpy but I don't see anything relevant.
Here's a blog post that describes how the Windows Azure Fabric Controller monitors instance health.
Aside from that, the controller calls a StatusCheck event, every 15 seconds, that you can handle. If you want to pull yourself out of the load balancer (maybe based on some internal data your instance has), you just call SetBusy() on the RoleEnvironmentStatusCheckEventArgs object. This takes you out of the load balancer until the next check.
I think the mechanism is the same as the one used for WebRoles
the Azure RoleEnvironment performs a StatusCheck - see http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.serviceruntime.roleenvironment.statuscheck.aspx
If you want to tell the service you are busy then call SetBusy() when this event fires

Resources