Trouble handling NServiceBus events on IIS with multiple worker processes - c#

I'm developing a web application subscribing to NServiceBus events being published by a backend application. With one worker process this works as expected, but with multiple IIS worker processes on the same IIS server, only one process receives the events. I suppose this is due to all worker processes sharing the same input queue and therefore "stealing" events from each other. My question therefore is how to ensure that the event handlers in every worker process receive the events they have subscribed to?
While generating input queue names dynamically would solve the problem, it would soon leave a lot of unused queues around the system.
This sounds like a pretty common problem and so should have a common solution?
ANy feedback would be appreciated
/Magnus

Unfortunately NServiceBus does not support web gardens.
We will consider adding support for web gardens in the future, based on user demand.
We suggest for the mean time to consider virtualization as a scale out solution instead.
I have raised an issue, see https://github.com/Particular/NServiceBus/issues/2015, please consider adding extra comments to the issue.

Related

C#: design pattern for background work / communication without abusing Task.Run

I have a c# .net (4.7.2) rest api web app which needs to communicate (http) periodically with a group of up to 100 devices.
Currently we basically have a event handler that intially makes a single Task.Run (containing communication work*) per device. At the end of each such a Task.Run an event will be triggered so that this event handler fires again. So when having 100 devices we have approximatley 100 short-lived "background worker threads" running, which all die and cause a Task.Run again in a time period of ~ 3 seconds.
As it turns out this seems to be very expensive - in fact I am suspecting this architecture to cause severe problems like 'freezes' from time to time.
I understand that this is not best practise and that calling Task.Run is not free, but spinning up
up to 100 threads periodically should not be that big of an issue - at least that's what I thougt.
I don't care if the the Tasks beeing enqueued on the thread pool are worked off with a little delay because of Task management.
So I am wondering which architecture would be appropriate for a dynamic growing/shrinking background work load that consists mainly of "asyncable" code.
Despite of following best practises - is there really a big pit fall here with this Task.Run / Eventhandler approach?
*The main work consists of establishing a http connection and waiting for its result. Finally database read/writes have to be done. So it could be done by using async code.
I recommend you to use Hangfire to do this continuously. You can access your device via APIs and hand fire connect with all of its and you main devices.
It can show you reports and state of activities and threads and you can program it. I found out it is more reliable and stable that running a thread!
On the other hand, you can use "Observer Design Pattern" in your sub-applications. When the time or Event fire all subscribers in your code can fire and do answer to you.
you can read more in here :
Observer Design Pattern
For the problem that you describe perfectly suits Durable Task Freamork.
From the box, you will have:
possibility to scale (due to the architecture of DTF use ServiceBus and each instance can process work)
you can control the execution
provides the possibility to configure the level of parallelism
Also for long-running processing, you can use Azure Durable Function.

UWP App Service threading model

I try to develop an extension for Microsoft Edge based on native messaging and the official guide provides the example. And there is synchronization of access to the dictionaries of AppServiceConnections and their Deferrals in the OnBackgroundActivated method, but there is no such a thing in other event handling methods...
So my question is about UWP App Service threading model. Is it guaranteed that only one event handling method can be performed at a time? Or should I provide a correct synchronization of access to my data?
Is AppServiceConnection thread safe? Can I use SendMessageAsync from different threads at the same time? Or should I synchronize its usage?
I guess your issue is that you didn't see lock keyword inside events like OnAppServiceRequestReceived, OnAppServicesCanceled and so on, which is to do thread synchronization, and you're not sure if you should do this by yourself.
I think the answer should be no.lock inside OnBackgroundActivated is ensured to set correct desktopBridgeConnectionIndex or connectionIndex. Without the keyword lock inside these event handles not means that the event handle must be triggered only one time at a time. For one app service, if client A is connecting the app service, at the same time, another client B asks for the same app service, for this scenario the app service will spin up another instance of the same background task. So that for client A, its app service connection there is no side effect on client App B. In another words, each app service connection has its own instance, messages sending based on one app service connection have no influence with others. You may reference this video to look more details about app service, app service relative is about starting from 25th minute.
If you check the code snippet inside the event, you may see there are code lines to judge the request is from which app service connection, for example this.desktopBridgeConnection = desktopBridgeConnections[this.currentConnectionIndex].You will send message to correct AppServiceConnection, and this should be thread safe. If you met actual thread save issue when performing this, you could ask issue with testing details.

Messaging / Triggering between WaIISHost and W3WP (Azure web role)

So I want the Webrole to react to Configuration changes, which involved capturing the event "Changing" and update a static dictionary (contains my Features setup)
Sounds like a simple task, it just I then realised that any changes made in the static object in WaIISHost (which handle the Changing event) is not accessible by the W3WP process.
I'm thinking of using either a message queue (using Azure queues) or Anonymous Pipe (but still don't know how to set that up)
Anyone knows how to either passon the Changing/Changed event from the WaIISHost process to W3WP, or if not possible, best way (i.e. least complicated) to communicate between the 2?
Many thanks!
You can subscribe to the RoleEnvironment events from within w3wp.exe and then the events will be raised in both processes (w3wp.exe and WaIISHost.exe). Global.asax is a good place to do this.

MSMQ C# implementation using service (ServiceBase)

I will be using MSMQ in C# to read messages; and I am putting this in Window Service so on OnStart I will start reading messages using queue.Receive method which would be blocking/synchronous call. And OnEnd method I want to stop the queue with queue.Close(); queue.Dispose().
Is there any drawback of this approach ?
Thanks
Ocean
This is incorrect approach. OnStart is called once when service starts, you should put initialization logic. For example start thread that will call Receive in a loop.
This is a fairly common pattern, but it has some drawbacks.
First, you should consider using a thread pool (or the .NET parallel libs in 4.0) to process your messages asynchronously. Whether or not your queue reader can be asynchronous depends a lot on your transaction pattern. Will the processing be atomic?
Second, you should also consider using a timer (System.Timers.Timer) which you start in your OnStart and end in your OnEnd, and which reads one or more messages from the queue on each timer event.
Third, you should seriously consider just using the WCF MSMQ binding, which handles a lot of the complexity of this stuff.
See: http://jamescbender.com/bendersblog/archive/2009/04/04/the-one-where-i-talk-about-the-msmq-binding.aspx
Your approach looks fine to me. My only advice is to make sure that every machine on which you intend to deploy the Windows Service is either in the same Domain, or are in Domains with mutual trust and that reside within the same Forest. I had a problem recently with a solution that I inherited that utilised MSMQ, and that worked much the same way as you have proposed above. It was tested as working on a single domain with no performance issues. Unfortunately, the client was in the process of a merger, and when it came time to implement the solution across the wider company it turned out that the solution had to be implemented on machines that existed in different domains in different Forests, in which case MSMQ wont work at all and another approach entirely had to be used.

ASP.NET Mvc: How to trigger a notification event after a date?

I'm trying to build a planner web app using ASP.NET MVC 3.
One of the problem I don't know is how to automatically trigger an event(send mail whatever) when the time is one that spot?
Who can help? Thanks.
In addition to your front end asp.net site that allows configuration of events, you will need a backend service attached to the database that sends out the notifications. This back end service should keep track of the last time it processed events. It will wake up periodically and process all newer events. The period will be determined by how 'real time' you want your responses. Once every minute is probably as fine grain as you may need.
Personally I would not make the web app handle that. Instead, I'd have a service that runs in the background or use the Windows Schedule to run certain application every x min/hour.
But with ASP.NET, you could start a background thread that calls some function every x time.
Here's more on that: http://flimflan.com/blog/SafelyRunningBackgroundThreadsInASPNET20.aspx
I hope this helps you in the right direction.
Timed events can be handled with threads or a service.
The downside to threads and timers that's not often considered is that often IIS will restart, which will restart your threads and timers. A service is much more stable and will fire automatically every so often without requiring you to keep track of state data (such as the current time).
A service or a scheduled task is the best fit for this problem, but if your hosting provider (assuming you aren't self-hosting) does not allow for this, or they want a lot more money for this ability, then an alternative you can consider,if running in .NET 4.0, it always having the application pool stay alive.
This blog post by Scott Guthrie describes how this can be done:
http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx

Categories