Unsubscribing events before shutdown of self hosted endpoint - c#

I have a bunch of wpf test clients which are self hosted nservicebus endpoints. The test clients are subscribing to several events of another endpoint at startup. Before the test clients are shutting down, I want their subscriptions to be removed. The first idea I came up with, was to use IWantToRunWhenBusStartsAndStops.Stop() where I unsubscribe all events.
The problem with this solution is that when nservicebus invokes IWantToRunWhenBusStartsAndStops.Stop() some objects have already been disposed. e.g. when nservicebus tries to create an object of TransportDefinition to decide if the endpoint has support for centralized pub\sub.
I'm not sure, if the problem only occurs in a self hosted scenario. Are there any suggestions?

Related

Can a Service Fabric stateless service notify other instances?

I have an Azure Service Fabric application with one stateless service. I have multiple virtual machines running multiple instances of this service.
Is there a way for one instance to notify all other instances that something happened? I was thinking about using Azure Service Bus to subscribe all instances for some topic, and raise a message when an event occurs. Is there a better way?

Azure Service Bus pub/sub to multiple azure web app instances

I am trying to achieve a pub/sub with azure service bus.
I started with this tutorial and it worked so far:
https://azure.microsoft.com/en-gb/documentation/articles/service-bus-dotnet-how-to-use-topics-subscriptions/
But in my dedicated case i am not exactly sure how i should do it exactly:
I have a web api running on azure web app that is scaled to three instances.
I have a console application client that triggers some messages to a dedicated topic.
What i want to achieve is, that all three instances of the web api get the messages delivered that is send to the message bus.
So it is a fire forget action:
Client sends message to topic
Every subscriber that is CURRENTLY subscribing to this topic should get the message
I am not interested in older messages that were sent when the subscriber was inactive/offline. I am just syncing an in memory cache over these instances so it is really a short living info when i need to know which keys i have to invalidate. but it is important that every subscriber gets the information to avoid stale data.
I am not exactly sure if i have to create a subscription dynamically in the startup code of the web api so that every instance has its own subscription or if i can subscribe all web app instances to the same subscription?
I would like not to dynamically create subscriptions since i don't know when to remove them again (e.g. scaled down to 2 instances instead of three).
but i was unable to find any documentation how to do this and if it is okey that multiple clients subscribe to the same subscription or if i need to create a subscription per client.
I am not exactly sure if i have to create a subscription dynamically in the startup code of the web api so that every instance has its own subscription or if i can subscribe all web app instances to the same subscription?
Service Bus subscribers adopt the Competing Consumer pattern by default. You must create a unique subscription for each Web API instance in order each instance to receive a copy of the message. It will be easiest to do this when the Web API instance starts up.
I would like not to dynamically create subscriptions since i don't know when to remove them again (e.g. scaled down to 2 instances instead of three).
You can configure the subscription to be auto-deleted after being idle for some period of time. "Idle" in this case would mean that the Web API instance has spun down and is no longer attempting to receive messages on the subscription. When creating the subscription set the AutoDeleteOnIdle time span for a brief duration, currently a minimum of 5 minutes. Now you can create a new subscription when the Web API instance starts and know that it will be automatically deleted soon after the Web API instance stops.
I am not interested in older messages that were sent when the subscriber was inactive/offline.
When creating the topic, set the DefaultMessageTimeToLive for a brief duration e.g. 5 seconds. This will ensure that new subscribers don't see old messages.

Safe to host NServiceBus publisher inside IIS?

I was wondering if it's safe to host an NServiceBus endpoint that serves as an event publisher inside IIS?
To clarify, we use an application hosted in IIS as our CRM system (Microsoft Dynamics CRM), and I want to use NServiceBus to publish an event when a contact's information is updated.
MS CRM allows the use of custom plugins to react on a contact update, and I intend to create a plugin that publishes a 'ContactUpdated' event through NServiceBus for that situation. Hence, this will effectively mean that my NServiceBus event publishing endpoint is hosted in IIS.
Now, I know that a self-hosted NServiceBus endpoint will create its own worker thread
to monitor incoming messages (in this case subscription messages) from the queue. Because IIS is free to unload a worker process if there are no more incoming web requests, it's usually not a good idea to use IIS to host long-running processes in.
However, I'd say that the NServiceBus queue monitoring thread does not qualify as a long-running process because it doesn't do any processing and can be stopped at any time: new subscription requests
will then simply be queued until the web application is restarted again.
I'm just wondering if the way IIS cleans up this NServiceBus thread is safe, from an NServiceBus perspective?
(Incidentally, I also found this article, but I have to admit that only the Scaling out argument resonates with me, and that is not relevant in our situation.)
Yes, it is safe to host an NServiceBus publishing endpoint in IIS.
As you said, if IIS were to unload your worker process then any pending subscription requests would be waiting in the queue. This is reasonable - as long as you don't make any assumptions about the order in which a subscription request would be handled and a new event published.

Calling SignalR client from webfarm

I have the following message transport scenarios
Client -> Calls SignalR -> Calls NServiceBus -> Process Message internally -> Calls NServiceBus Gateway service with Result -> Calls SignalR Hub -> Updates the client with result.
In choosing whether to use SignalR vs. long polling, I need to know if SignalR is scaleable. So in doing my homework I came across SignalR on Azure Service Bus. The setup is done on the Global.asax application start.
Ultimately I need to be able to do this, from inside an NServiceBus handler:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.Group(group).addMessage(message);
The question is if context will be jacked up, because I'm (potentially) calling it from another machine than the one the client was connected to?
Also what is the sharding schema that the SignalR implementation uses to seed the topics? I know I can configure it to use N-number of topics, but how is it actually determining which message goes to which topics and if it's relevant from an external caller PoV.
You should be able to use GlobalHost.ConnectionManager.GetHubContext in any application where you have registered ServiceBusMessageBus as your IMessageBus via SignalR's GlobalHost.DepenencyResolver. This is done for you if you call GlobalHost.DepenencyResolver.UseServiceBus(...) in the application.
If you do this, a message will be published to Azure Service Bus for each call to addMessage or any other hub method on the IHubContext returned from GetHubContext. If there are subscribed clients connected to other nodes in the web farm, the other nodes will pick up the message from Service Bus and relay it to the subscribed clients.
Which topic a message goes to should not be relevant from the PoV of an external caller. You can use multiple topics to improve throughput, but for most use cases one should be sufficient.
If you choose to use more than one topic, you can think about the topic a message goes to as being essentially random. The only thing that is guaranteed is that messages from the same sender will go to the same topic. This allows SignalR to keep messages from the same sender in order.
Caveat emptor: SignalR has not yet had an official release supporting scale out. The 1.1 version will be the first release to support scale out officially.

How to implement single publisher and multiple subscribers asynchronous message system in C# using WCF and MSMQ?

I have searched a lot, but still I had few doubts about MSMQ implementation of WCF service.
Hence I have put this quetion.
I want to implement single publisher and multiple subscribers asynchronous message system.
I have decided to use WCF service as the publisher.
I have multiple instances of the window service on different machines as the multiple subscribers.
Q. I want to know that, how this model can be implemented as the old MSMQ approach?
The object of following type would be used in the message
[Serializable]
public class Message
{
public string Signal{get;set;}
public Guid Identifier{get;set;}
}
In the above class, Identifier would be used by the windows service to decide whether the message was published for that service or not.
Q. How the different window services will read the same queue?
Q. Where the queue should be hosted?
Q. Is it possible to send the acknowledgement from Window service(subscriber) to WCF service(publisher)?
Any help would be appreciated.
In answer to your questions:
I want to know that, how this model can be implemented as the old
MSMQ approach?
First off, MSMQ does not support publish subscribe out of the box.
How the different window services will read the same queue?
So in publish subscribe, there in no ONE queue. Instead there are multiple queues, in fact one per participant in the pub sub scenario. So each publisher has a queue and each subscriber has a queue.
This configuration enables subscribers to send subscribe/unsubscribe messages to the publisher, and allows the publisher to send messages to the subscribers as necessary after evaluating the subscriptions.
Where the queue should be hosted?
These queues can be hosted locally to each participant, or can be hosted together in some clustered location.
Is it possible to send the acknowledgement from Window
service(subscriber) to WCF service(publisher)?
MSMQ does provide basic support for request/response messaging via response-queue and correlation-id message header fields, though this is not truly out of the box (as you are required to consume and program against these values)
If you are not required to use WCF there is a fairly mature platform called nservicebus which sits on top of MSMQ and does provide support for all the messaging patterns you need.

Categories