Server architecture question. (WCF+NServiceBus) - wcf

First of all i will describe current state:
Server consists of several WCF services, hosted in one or several win services on diffirent machines.
Service responsible for recieving data from diffirent devices. Communication with devices is implemented using sockets. Service instance mode - singleton.
Data broker service - responsible for persisting data and sharing in by request. Instance mode - singleton.
Configuration service - responsible for changing configuration database and working with administration console(WPF app, like SSMS). Handles connections from console, subscriber management, etc. Instance mode - singleton.
Client access service - quite the same as above thith management of clients but also notifyes clients of new data, and acts like facade to service bus. And singleton again.
Identity management service - Checks permissions and returns result. Singleton.
All of those services are connected with NServiceBus and i realy like how it works at this moment.
But:
Too many singletons. Mainly because to use servicebus i must have single instance of it afaik. I dunno maybe i can use nservice bus in session mode, but dont know how to handle issue that all of those services will use one queue.
And what if i will have 300+ clients? singleton can become unresponsive..
And i wanted to ask for some critics about all of this and maybe some one could suggest something.
Thanks in advance.
Alexey

Alexey,
While you should only have one instance of the bus per process, you can put that instance in a globally accessible place (as shown in the AsyncPages sample), and use that from non-singleton objects like web pages and WCF services.
Also, it is probably not appropriate to have all your services using one queue. Without better understanding your situation, I'd give the default recommendation of one queue for each of the services you identified.
Hope that helps.

Related

WCF central service with multiple clients

i can't find any good architecture explanation of how can WCF SHOULD be part of a main-server with multiple clients.
in my solution, i want to have a central WCF service (hosted in windows-service on windows server machine).
The central service is the only one that's connected to the DB.
all the clients, are connecting to this main service, login, and get having a duplex communication.
via that main service, one client can connect another one. or when one client using the main service to change the DB, the main service updates all other clients.
for doing that, i added in the main service the InstanceContextMode.Single attribute, and in the windows-service, i init ServiceHost with the WCF-service singleton.
it works. so so..
i can continue and search where the problems are, and how to fix them, but it looks like something here is not right, like i'm not supposed to do it this way.
i could really use an advice on how WCF service should be used as a main service with multiple clients, that require common memory.
it's basically for ~20 clients with not too intensive operations, but i still want the option to let them all communicate simultaneously with the main service, and not only one by one.

Simulating a transient error for Service Bus

I'm writing an application which will use the Azure Service Bus. For local development I'm using Windows Server Service Bus to provide the same services (the code to use either is identical).
I want to write the application to be tolerant of transient errors when sending or receiving messages. To that end, I want to be able to test the fault-handling code can deal with the local Service Bus instance suddenly being unavailable during execution of various operations.
Ideally, I'd want to write some automated integration tests around these scenarios, but I appreciate that may not be practically achieved.
What can I do to simulate transient errors on my local Service Bus?
One easy thing would be to call the stop-sbservice (affects one node) or stop-sbfarm (affects the entire farm) cmdlets. This would let you simulate a servicebus outage locally. You can then call start-sbservice or start-sbfarm to bring the service back and validate that your code recovers properly. This approach also has the added benefit that you control when the service returns (compare to just crashing the process). This page has information on the available cmdlets.
If that's not enough, another approach that I've used in the past is to shut down the network interface, or, if the server is in another machine, put up a firewall on the ports used to communicate to service bus.

Running multiple instances of the same XPC service (NSXPCConnection)

Is it possible to run multiple instances of the same XPC service using the XPC APIs found in Foundation.framework (NSXPCConnection, etc.)? The docs don't provide much insight on this matter.
EDIT: Did a quick test, and it seems like only one instance of the service is running even though I created two XPC connections. Is there any way to have it run another instance?
A bit late, but the definitive answer to this question is provided in the xpcservice.plist manpage:
ServiceType (default: Application)
The type of the XPC Service specifies how the service is instantiated.
The values are:
• Application: Each application will have a unique instance of this service.
• User: There is one instance of the service process created for each user.
• System: There is one instance of the service process for the whole system. System XPC Services are restricted to reside in system frameworks and must be owned by root.
Bottom line: In most cases there is a single instance of an XPC Service and only in the case where different applications can connect to the same service (not even possible when the service is bundled with an app), will there be multiple instances (one-instance-per-app).
I believe XPC services designed for one instance per multiple connections. Probably, it is more convenient to manage named pipes with one running executable. So, the most likely it is impossible to create multiple instances simultaneously.
Since XPC services should have no state, it should not matter, whether one ore more instances are running:
XPC services are managed by launchd, which launches them on demand, restarts them if they crash, and terminates them (by sending SIGKILL) when they are idle. This is transparent to the application using the service, except for the case of a service that crashes while processing a message that requires a response. In that case, the application can see that its XPC connection has become invalid until the service is restarted by launchd. Because an XPC service can be terminated suddenly at any time, it must be designed to hold on to minimal state—ideally, your service should be completely stateless, although this is not always possible.
–– Creating XPC Services
Put all neccessary state information into the xpc call and deliver it back to the client, if it has to persist.
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/xpcservice.plist.5.html
ServiceType key in XPCService dictionary: Application or User or System
But this ‘ServiceType’ is irrelevant… IF Service is embedded in an application bundle then it will only be visible to the containing application and will be, by definition, Applicaton-type services. A subsequent connection request from an application to a service will result in a new connection to an existing service.
I know I'm late to the party, but while you can't do this with plain XPC,
there's library (a component of OpenEmu) that should be able to do what you're asking: OpenEmuXPCCommunicator

How to renew subscriptions after IISRESET?

This is my scenario:
Web application with a self-hosted bus (publisher)
Windows service with NServiceBus.Host.exe (subscriber)
Imagine that trigger an IISRESET (never mind on the why I have to do that) that makes the bus re-initialize and lose the subscriptions that already had. I'm using MsmqSubscriptionStorage and the publisher (web app) implements the IAuthorizeSubscriptions interface.
How can I renew the subscriptions and also call the AuthorizeSubscribe()? Is that possible? What's your suggestion to this scenario?
If NServiceBus is properly using MsmqSubscriptionStorage, then after iisreset, the bus should initialize and load the existing subscriptions from the configured storage queue. This queue name can either be set by configuration or, if omitted, should default to a name based on an assembly plus "_storage". However, having never used this from a web application, I don't know what that would be in that scenario, since there is no class that implements IConfigureThisEndpoint.
That said, trying to publish an event from a web application is a very icky business, and it's generally advised that you avoid just that.

What are the advantages of using WCF over frameworks like MassTransit or hand written MSMQ client?

I am looking at using MSMQ as a solution to do asynchronous execution in my upcoming project. I want to know the differences between using WCF and frameworks like MassTransit or even hand written MSMQ client to place/read task off MSMQ.
Basically the application will be several websites (internal through LAN or external through the Internet) reading/writing data through a service layer (be it WCF or normal web service). Then this service layer will do one of two things: 1. write data to database 2. and/or trigger the background process by placing a message in the queue. 3. obviously it can also retrieve data from database. The little agent (a windows service) on the other side of the queue will monitor the queue and execute based on the task command.
This architecture will be quite easy to scale (add more queues and agents) and easy to implement compared to RPC or distributed execution or whatever. And the agent processing doesn’t need to be real time. And the agent and service layer are separate applications except they share the common domain objects and Repositories etc.
What do you think? Architecture suggestions for the above requirements are welcomed. Thank you!
WCF adds an abstraction over MSMQ. In fact, once you define compatible contracts (operations must be OneWay), you can switch out MSMQ in the config, transparently. (For instance, you could switch to normal HttpWS or a NetTcp binding.)
You should evaluate the other WCF benefits, like security and so on, to see how those fit in with your needs. Again, they should be reasonably transparent of the fact you're using MSMQ underneath. For instance, adding SOAP security and so on should "just work", independent of using MSMQ.
(Although, IIRC, you still need to login to the desktop on each machine that uses MSMQ, with the service account that will use MSMQ, to generate the certificate in the machines local profile. And then, it doesn't work very well from IIS6, since user profiles aren't loaded. A real pain in general, but nothing to do with WCF specifically.)
Apart from that:
Have you looked at SQL Server Service Broker? After using MSMQ + WCF and SSSB, I think that SSSB is vastly easier to configure and manage. SSSB works with T-SQL commands over any SQL client (I use it from Mono, on Linux, with transactions). It'll also give you transactional send/receive, even remotely (I think MSMQ 4 now allows this). It really takes a lot of the pain away from message queuing, and if you're using SQL Server already...
SSSB is often overlooked since the SQL Management Studio doesn't have GUI designers for it all, but it isn't hard and is a great option. The one downside is that if you want local send capability (i.e., queue message when network is down), you'll need to run a local SQL Express instance.
Your architecture seems sound and reasonable. However you should consider using the WCF net MSMQ transport over hand coded MSMQ classes. WCF wraps this common functionality into a nice programming model. Also I believe there is some improvements in the protocol used by wcf compared to basic System.Messaging
Have a look at the value-add over plain MSMQ:
http://readthedocs.org/docs/masstransit/en/latest/overview/valueadd.html
In summary, you get a lot of messaging concepts clearly presented in the API with MassTransit; to an extent you wouldn't have if you hand-coded it or used WCF.