The project I am currently working in, we have over 30 wcf services, which are called a lot in our web application, we ran into performance issues and once of the solutions was to cache the proxy. So what we did is create a dictionary object and using the endpoint name as key, cached the channel factory object so that subsequent calls will pull from the cache rather than re-instantiating the channel factory object at every call. There are many implementations over on other forums.
But we ran into one issue, the way our system is setup is that our services reside on one or more servers, of which only one is active at any one time, if a server fails then another is used as a fail safe. When creating the channel factory before putting into the cache, we can get the latest endpoint address for a given service and then instantiate it. However in this scenario, if a server fails and we pull a channel factory object from the cache, it'll refer to an old endpoint address.
I was checking on forums whether it was possible to update the endpoint address in channel factory object, if this was doable I could update the channel factory object in the cache and use it from then, I don't think this is possible.
The only thing I came up with recently is, that we check for a possible 404 fault exception which will happen when an old endpoint address is hit, then get the latest endpoint address and recreate the channel factory, and update that in the cache.
If you guys have any other ideas, would be helpful. Kinda stuck at this point.
You can create the channel factory without specifying an endpoint address and pass it to the method CreateChannel later:
public TChannel CreateChannel(EndpointAddress address)
Related
Could please Give RealTime Example when we should use AddSingleTon and when AddScoped and When should use AddTransient.
As far as I know, the Singleton is normally used for a global single instance. For example, you will have an image store service you could have a service to load images from a given location and keeps them in memory for future use.
A scoped lifetime indicates that services are created once per client request. Normally we will use this for sql connection. It means it will create and dispose the sql connection per request.
A transient lifetime services are created each time they're requested from the service container. For example, during one request you use httpclient service to call other web api request multiple times, but the web api endpoint is different. At that time you will register the httpclient service as transient. That means each time when you call the httpclient service it will create a new httpclient to send the request not used the same one .
Transient — Services are created each time they are requested. It gets a new instance of the injected object, on each request of this object. For each time you inject this object is injected in the class, it will create a new instance.
Scoped — Services are created on each request (once per request). This is most recommended for WEB applications. So for example, if during a request you use the same dependency injection, in many places, you will use the same instance of that object, it will make reference to the same memory allocation.
Singleton — Services are created once for the lifetime of the application. It uses the same instance for the whole application.
One of my service methods returns an non-primitive object of my own class.
The service is cluster-singleton, so I expect it to be used mostly through it's proxy on different nodes.
What will this method return? Will it be a proxy of my object too? Or will it attempt to serialize it on remote and deserialize it on a local machine?
The trick is that the object returned contains a reference to the service itself.
If serialize/deserialize happens, I expect Ignite to replace this reference with a service proxy during deserialization on a local machine. Will it happen?
Otherwise I expect it to make a proxy out of the returned object, though it is a little bit worse scenario due to subsequent bigger network interactions while working with this object.
The worst scenario would be that the service proxy can't return anything except primitives or standards.
Digging into the source code and the docs, I failed to locate my answer, please advise. What will happen:
deserialize/replace internal refs;
proxyfy;
fail;
Other?
will happen - your custom object will be serialized and sent across the network.
What happens to your service, I'm not entirely sure. Maybe it will be also serialized and sent across network :) of course, in this case it will become a different instance.
Now, if you had your object refer to service proxy instead of the service itself (raw object outside of Ignite), the result may be different.
I'm using WCF to create a connection beween a server app and client app.
Because I'm using NetTcpBinding, I want to keep alive the channel created by:
T proxy = ChannelFactory<T>.CreateChannel();
I bring the proxy instance into my app to communicate with server. At some moment, I renew this proxy, with a different factory. But I want to release resources from the first factory, by disposing it. But I don't wan't to manage factories and keep a reference to.
Is there a way with the proxy instance to retrive the channel associate to dispose it ?
Like ...
var commObj = (ICommunicationObject)proxy;
commObj.Factory.Dispose();
Thanks
Unfortunately, it is not possible, because Channels and Factories are not linked. But I think your approach is not correct. You should keep a reference to the factory and create Channel as needed. Re-using Channel can be a problem in some cases. A channel can be faulted, but the inner factory will still be valid. Creating a factory has a real cost, and some .net 3.5 SP1, factories are internally stored in a static cache.
I have been trying to get up to speed on Named Pipes this week. The task I am trying to solve with them is that I have an existing windows service that is acting as a device driver that funnels data from an external device into a database. Now I have to modify this service and add an optional user front end (on the same machine, using a form of IPC) that can monitor the data as it passes between the device and the DB as well as send some commands back to the service.
My initial ideas for the IPC were either named pipes or memory mapped files. So far I have been working through the named pipe idea using WCF Tutorial Basic Interprocess Communication . My idea is to set the Windows service up with an additional thread that implements the WCF NamedPipe Service and use that as a conduit to the internals of my driver.
I have the sample code working, however I can not get my head around 2 issues that I am hoping that someone here can help me with:
In the tutorial the ServiceHost is instantiated with a typeof(StringReverser) rather than by referencing a concrete class. Thus there seems to be no mechanism for the Server to interact with the service itself (between the host.Open() and host.Close() lines). Is it possible to create a link between and pass information between the server and the class that actually implements the service? If so, how?
If I run a single instance of the server and then run multiple instance of the clients, it seems that each client gets a separate instance of the service class. I tried adding some state information to the class implementing the service and it was only retained within the instance of the named pipe. This is possibly related to the first question, but is there anyway to force the named pipes to use the same instance of the class that is implementing the service?
Finally, any thoughts on MMF vs Named Pipes?
Edit - About the solution
As per Tomasr's answer the solution lies in using the correct constructor in order to supply a concrete singleton class that implements the service (ServiceHost Constructor (Object, Uri[])). What I did not appreciate at the time was his reference to ensuring the service class was thread safe. Naively just changing the constructor caused a crash in the server, and that ultimately lead me down the path of understanding InstanceContextMode from this blog entry Instancecontextmode And Concurrencymode. Setting the correct context nicely finished off the solution.
For (1) and (2) the answer is simple: You can ask WCF to use a singleton instance of your service to handle all requests. Mostly all you need to do is use the alternate ServiceHost constructor that takes an Object instance instead of a type.
Notice, however, that you'll be responsible for making your service class thread safe.
As for 3, it really depends a lot on what you need to do, your performance needs, how many clients you expect at the same time, the amount of data you'll be moving and for how long it needs to be available, etc.
I am using wcf 4 and trying to transparently transfer context information between client and server.
I was looking at behaviors and was able to pass things around. My problem is how to flow the context received in the incoming headers to the other services that might be called by a service.
In the service behavior I intercept the the message and read the headers but don't know where to put that data to be accessible to the next service call that the current service might make.
What I am looking for is something like:
public void DoWork()
{
var someId = MyContext.SomeId;
//do something with it here and call another service
using(var proxy = GetProxy<IAnotherService>())
proxy.CallSomeOtherMethodThatShouldGetAccessTo_ MyContextualObject();
}
If I store the headers in thread local storage I might have problems due to thread agility(not sure this happens outside ASP.NET, aka custom service hosts). How would you implement the MyContext in the code above.
I chose the MyContext instead of accessing the headers directly because the initiator of the service call might not be a service in which case the MyContext is backed by HttpContext for example for storage.
In the service behavior I intercept
the the message and read the headers
but don't know where to put that data
to be accessible to the next service
call.
Typically, you don't have any state between calls. Each call is totally autonomous, each call gets a brand new instance of your service class created from scratch. That's the recommended best practice.
If you need to pass that piece of information (language, settings, whatever) to a second, third, fourth call, do so by passing it in their headers, too. Do not start to put state into the WCF server side! WCF services should always be totally autonomous and not retain any state, if at ever possible.
UPDATE: ok, after your comments: what might be of interest to you is the new RoutingService base class that will be shipped with WCF 4. It allows scenarios like you describe - getting a message from the outside and forwarding it to another service somewhere in the background. Google for "WCF4 RoutingService" - you should find a number of articles. I couldn't find antyhing in specific about headers, but I guess those would be transparently transported along.
There's also a two-part article series Building a WCF Router Part 1 (and part 2 here) in MSDN Magazine that accomplishes more or less the same in WCF 3.5 - again, not sure about headers, but maybe that could give you an idea.