Can WCF handle simultaneous calls to the same endpoint? - c#

I am developing WCF application under Windows Service which is exposing one endpoint. There can be about 40 remote clients who will connect to this endpoint over local area network at the same time. My question is whether WCF can handle multiple calls to the same endpoint by queuing them? No request from any client can be lost. Is there anything special I have to consider when developing application to handle simultaneous calls?

You can choose whether the requests should be handled asynchronously or synchronously one after another.
You can set this behavior via the InstanceContextMode settings. By default WCF handles requests ByCall which means one instance of your service will be created for each incoming request. This allows you to handle multiple requests in parallel.
Alternatively you can configure your service to spin off only one instance which ensures each request is handled after the other. This effectively is the "queuing" you mentioned. You can set this behavior via InstanceContextMode.Single. By chosing this mode, your service becomes a singleton. So this mode ensures there's only one instance of your service, which may come in handy in some cases. The framework handles the queuing.
Additionally you could set ConcurrencyMode.Multiple which allows your single instance to process multiple requests in parallel (see Andrew's comment).
However, be aware that the queued requests aren't persisted in any way. So if your service gets restarted, the not yet finished requests are lost.
I'd definitely recommend to avoid any kind of singleton if possible.
Is there anything that prevents you from chosing the parallel PerCall-mode?
For more details have a look at this: http://www.codeproject.com/Articles/86007/ways-to-do-WCF-instance-management-Per-call-Per

Here are some useful links:
https://msdn.microsoft.com/en-us/library/ms752260(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/hh556230(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute(v=vs.110).aspx
To answer your question, no calls will be lost whatever you choose. But if you need to process them in order, you probably should use this setup for your service
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, EnsureOrderedDispatch = true )]

Related

How does WCF handle instancing and concurrency?

I try to understand how WCF handles instancing, concurrency and threading.
For example, if I configure the instance context mode to PerCall and concurrency mode to singe, every request creates a new instance of the WCF service. What does that mean related to the threads, which a created server side?
I guess that instancing and concurrency is not strong related to threading. Is it right that, to the given example, every request is queued by the "main" I/O ThreadPool to be executed by the worker thread? Or is every request creating a new instance and thread that executes this request?
if I configure the instance context mode to PerCall and concurrency
mode to singe, every request creates a new instance of the WCF
service. What does that mean related to the threads, which a created
server side?
If you use Per-Call instancing then the service instances are all single threaded, as each incoming request is serviced by a new instance of the service. So specifying concurrency is not relevant in this scenario.
I guess that instancing and concurrency is not strong related to
threading
I'm not sure how you arrive at this conclusion.
Addressing comments below this post:
In a Per-Call mode, for each call we create an instance of the
service. If we are in a single thread mode, there is one thread
handling these instances so we serve requests in a sequential way
These two statements are contradictory. If we create a new instance per request, then the service does not handle multiple requests sequentially. It will create a new instance per request.
(In PerCall mode) if the concurrency mode is multiple, there are many threads executing
the instances methods so we serve request in parallel way
This is not correct. Multiple requests will each be handled by their own service instance.
Handling a call in a service instance takes one thread. The call handling code may well be multi-threaded but this is internal to the service and WCF concurrency mode does not affect the execution of call handling code.
Other calls to the service will result in new instances of the service being created. So while you certainly can set concurrency mode to multiple, you will never get more than one thread handling requests to a service instance.
Therefore setting concurrency mode to multiple in per call instancing does not make any practical difference to the behavior of the service.

share data status on different instances of WCF

I have two servers(and could be more later) with a WCF service, both behind a load balancer. The client application, in multiple IS servers(also loadbalanced), call the WCF to do some action, lets say a Save.
The same data, lets say Client information, could be opened by several users at same time.
The Save action can be, then, be executed from several users at the same time, and the call will go to different WCF servers.
I want that when a user call Save from UI, and there is already a Save in progress from another UI over the same Client data, then the second user be alerted about it.
For that, all WCF instances should know about actions been executed in other instances.
How can I synchronize data status between all WCF server instances then ?
I dont want to share the data, just some status of the data(opened, save in progress, something like that)
please advice, thanks,
I'm working with c#/.NET4
Added: WCF is actually hosted inside a windows service.
The problem you are having is one of resource management.
You are trying to resolve a way how you can get your service clients to somehow all know about what open handles each other have on internal state within your service, and then force them to orchestrate in order to handle this.
Pushing this responsibility onto your clients is going to make things much more complex in the long run. Ideally clients should be able to call your service in as straightforward manner as possible, without having to know about any other clients who may be using the service. At most clients should be expected to retry if their call was unsuccessful.
Normally you would handle these situations by using locking - the clients could all commit changes simultaneously and all but one will have to retry based on some exception raised or specific response sent back (perhaps including the updated ClientInformation object), depending on how you handle it.
If you absolutely have to implement this notifications stuff, then you could look at using the WCF duplex bindings, whereby your service exposes a callback contract which allow clients to register a handler for notification which can be used to send notifications to all clients on a different channel to the one the request was made on. These however, are complex at best to set up and do not scale particularly well.
EDIT
In response to your comment, the other half of your question was about sharing state across load balanced service endpoints.
Load balancing wcf is just like load balancing websites - if you need to share state across them you must configure some backing data store which all services have access to.
In your case the obvious place would be the database. You just need to make sure that concurrency/deadlock related problems are caught and handled in your service code (using something like NHibernate to persist the data can help with this). I just don't see that you have a real problem here.

WCF to WCF Communication

I have an architecture, where there are the following constituents:
External Applicaton (EA) - Third party who makes a request to WCF Service
WCF Service (WS) - All the business logic
Pub-Sub Service (PSS) - Handles publishes and subscriptions
Internal Application (IA) - Subscribes or unsubscribes to Pub-Sub (with CallBacks)
The external application (EA) references the WCF service (WS) and makes a call to a specific method, to which all Internal Applications (IA) should be notified through the Pub-Sub Service (PSS).
The problem I have is in deciding whether it is feasible or best practice to get one WCF Service (WS) to communicate with another WCF Service (Pub-Sub Service). I've read that this is not a good idea given that requests are processed in a synchronous manner and this could cause inconsistencies in service delivery.
My specific question based on that is - can someone share pro's and con's of allowing two WCF services to talk to one another; or is this a non-issue?
Thanks
I agree with the other answers, however since a message oriented approach is not feasible with your available resources, I'll put it this way.
As long as your WCF services are acting as a client (your 'WS') and a server (your 'PSS'), it will share the pitfalls of any client-server application.
However, this assumes a couple of things:
a) Your 'WS' implements One-Way operations, or "fire and forget", towards your 'EA'. See here for reference: What You Need To Know About One-Way Calls, Callbacks, And Events. Otherwise, the 'EAs' will have to wait until your internal call to 'PSS' completes.
b) Your 'WS' channel is configured and has well and enough resources to handle the load, because One-Way operations aren't really asynchronous; if the channel can't handle the load the calls will queue up and block the client until resources are freed and execution can continue.
c) No constraints as to guaranteed, transactional or ordered delivery or any other messaging-like behavior is required.
But, a said before this sort of scenario really calls for a message based architecture. You have several points of failure and troubleshooting this chain of dependencies will be no fun.
I am totally agree with Steven. You should consider using message queue here. And the resources are below:
http://msdn.microsoft.com/en-us/library/ms751499.aspx
http://msdn.microsoft.com/en-us/library/ms731089.aspx
http://www.codeproject.com/Articles/34168/WCF-Queued-Messaging
Hope those will suffice. Thanks.

Reuse of WCF service clients

I have a WCF webservice that acts as a data provider for my ASP.NET web page.
Throughout the web page a number of calls are made to the web service via the auto-generated ServiceClient.
Currently I create a new ServiceClient and open it for each request i.e. Get Users, Get Roles, Get Customer list etc.... Each one of these would create a new ServiceClient and open a new connection.
Can I make my ServiceClient class a global or statically available class so that all functions within my ASP.NET web page can use the same client. This would seem to be far more efficient. Are there any issues with doing it this way? Any advice I should take into account when doing this?
What happens if I make multiple requests to a client? Presumably it is all synchronous so it shouldn't matter if I make 1 or 50 calls to it?
Thanks
When session (wsHttp with security context or reliable session) or connection (net.tcp, net.pipe) oriented binding is used you have to handle your proxy in the way you want to handle the session. So if you share the proxy, all calls will be handled in single WCF session (by default handled by single service instance). But you have to deal with additional complexity like: Unhandled service exception will terminate your channel and following call from client will result in exception.
When session-less HTTP binding (basicHttp, webHttp) is used you can share your proxy or even make it static. Each call is handled separately, exception on a service will not fault the channel and it transparently reuses opened HTTP persistent connections. But because of this, there should be no big overhead to creating new proxy / channel.
So my suggestion is: When you need several calls to your service in single request processing in your ASP.NET application, use the same proxy / channel. But don't share proxy / channel among different requests.
I think using a ChannelFactory could take of your problem. If I'm right the ChannelFactory has a pool of your connection and re-uses the channels. The advantage of this is that the channels don't get instatiated each time, only the first.
Read more here: ChannelFactory
To handle the disposing of the channels you need some special handling since the channel can throw exception in dispose. I wrote a mapper to handle this, you can read about it here: http://blog.tomasjansson.com/2010/12/disposible-wcf-client-wrapper/

How to test the reactivity of a Windows Service?

I'm programming a monitoring application that needs to display the state of several windows services. In the current version, I can know whether a service is Running, Stopped, Suspended or in one of the pending states. That's good, but I'm wondering if there is a way to test if a service is actually responding? I guess it can be in a running state but not responding at all!
I am using the ServiceController class from System.ServiceProcess. Do you think that if a service is not responding, the ServiceController.Status would return an exception?
How would you approach the problem?
Thanks
EDIT
Seems that: ServiceController.Status can return 2 types of exceptions:
System.ComponentModel.Win32Exception: An error occurred when accessing a system API.
System.InvalidOperationException: The service does not exist as an installed service.
Nothing about reactivity.
This might be obvious, but have you tried talking to the service?
There's no common way to talk to a service, so there is no way Windows can interrogate whether the service is still responding as normal. It is perfectly normal for a service to go into a complete sleep waiting for external I/O to happen, and thus Windows would not get a response while the service is actually alive and functioning exactly as designed.
The only way is to actually send a request to it, and wait for the response, and for that you need some inter-process communication channel, like:
Network
Named pipes
Messages
Basically, if you need to determine if a service is able to respond, you need to check if it is responding.
The service controller types and APIs can only provide information on the basis of the service's response to those APIs.
E.g. you can create a service which responds to those APIs correctly, but provides no functionality on even numbered hours.
In the end you need to define "responsive" in terms of the services functionality (e.g. a batch processor is processing batches) and provide a mechanism (A2A API, WMI, Performance Counters) to surface this.

Categories