It appears that WAS will call ServiceHostFactory.CreateHost() once per each service implementation. How does WAS manage the lifetime of the ServiceHost/ServiceHostFactory? We have a custom factory/host that is occasionally being re-initialized. I'm wondering if WAS is recycling itself or it has some other reason to re-create the ServiceHostFactory/ServiceHost. I'm guessing the ServiceHostFactory gets fired up for the AppDomain and is a singleton, can someone confirm?
After instrumenting WCF, it appears that IIS/WAS will create a ServiceHostFactory per endpoint. From there it will spin up ServiceHosts as it sees fit, as this depends on your configuration.
The WAS manages the activation and lifetime of the worker processes. It manages the message-based activation and worker process recycling, to maintain the app resources. Reading your case, this affirmative is true.
You can use the Single InstanceContext, to handle all client request. Add the following attribute in the contract implementation:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
Also, take a look at the ServiceHost start operation, if is under a static method.
Related
I have a service which should begin when the server starts, and continue running for the entirety of the server lifetime. I would like to be able to manage the service (querying, modifying runtime options, etc) with a web frontend. While researching the best way to accomplish this, I came across two options: a scoped service with a singleton lifetime, and a backgroundservice/IHostedService. What are the differences between the two options, and when should one be used over the other?
Neither of those is actually a thing. The closest is the concept of a singleton and hosted services. A hosted service is a class that implements IHostedService and pretty much fits the bill of what you're looking for in that it will start at app startup and stop at app shutdown. ASP.NET Core 3.0 added a BackgroundService class, which is just an implementation of IHostedService with a lot of the cruft of defining what happens as start/stop/etc. covered. In practice, it usually makes more sense to inherit from BackgroundService, but you can also just implement IHostedService directly yourself.
"Singleton" is just a lifetime. All hosted services are registered with a singleton lifetime, but just because something is a singleton, doesn't mean it does anything special. You could, for example, register some random class as a singleton, and whenever it is injected, you'll always get the same instance. However, it will not do anything at startup or shutdown on its own.
Long and short, there are no differing options here. You're looking for a hosted service. That said, it only solves part of what you're looking for, in that it will "run" while the app is running. However, you can't really connect to it, or interact with it directly. It's not like a Web Api or something; it isn't exposed for HTTP requests, for example.
To "manage" it, you would have to expose some sort of API that would then interact with the service through code. For example, the docs provide an example of a queued background service that processes things added to the queue. However, to queue something, you would need to do something like create an API endpoint, inject the queue, and then use code to add a new item to the queue. Then, the actual hosted service would eventually pop that task from the queue and work on it.
I have a WCF service which need to initialize some expensive resources used for all incoming calls. Firstly I used a static variable to record its status, but the variable was reset on every call. Then I used a static service constuctor to init, but it got called on every incoming call. I tried to set InstanceContextMode to Single and PerSession, but neither of them worked.
Any ideas?
Setting your InstanceContextMode to Single is definitely the way to go if you need access to these resources across ALL calls to the service. What probably happened (just a guess) is your worker process is getting recycled, resulting in your initialization code have to run again when a new worker process is started. If that is what is happening, then take a look at this document to configure your application pool to use auto-start.
http://msdn.microsoft.com/en-us/library/ee677260.aspx
If this doesn't help then some additional details on how/where your initialization code is implemented would be helpful.
I am reading Juval Löwy's Programming WCF Sevices. It mentions:
In WCF, we have Context in which we have the instance. By default, the lifetime of the context is the same as that of the instance it hosts. We can have separate lifetimes for both.
WCF also allows a context to exist without an associated instance at all.
Why would we release the instance and keep the context empty?
Coincidentally I recently read the chapter you're probably referring to. In his book Löwy explains why this may be useful. First he writes:
WCF also allows a context to exist without an associated instance at all. I call this instance management technique context deactivation.
After mentioning this is typically done using an OperationBehavior with a specific ReleaseInstanceMode, he goes on and hints on when you could use this:
You typically apply instance deactivation on some but not all service methods, or with different values on different methods. [...] The reason you typically apply it sporadically is that if you were to apply it uniformly, you would end up with a per-call-like service, in which case you might as well have configured the service as per-call.
So you can use this "deactivation" to ensure only certain methods in a service with sessions behave as if they were part of a per-call service. The abovementioned MSDN article also explains this, in a different wording:
Use the ReleaseInstanceMode property to specify when WCF recycles a service object in the course of executing a method. The default behavior is to recycle a service object according to the InstanceContextMode value. Setting the ReleaseInstanceMode property changes that default behavior. In transaction scenarios, the ReleaseInstanceMode property is often used to ensure that old data associated with the service object is cleaned up prior to processing a method call.
Disconnecting the context from the instance makes sense when:
Instance creation is customized/extended. For example if you are creating your service instance with a custom IInstanceProvider with a dependency injection library (for example Unity) you might want a Unity lifetime manager to handle the service instance lifetime.
Some but not all operations result in an expensive service instance to be invalidated. For example: The service object loads a large expense resource as a part of creation. If the service operations called by the client modify or invalidate the resource, it needs to be disposed and reloaded for the next caller. If the operations don’t invalidate the resource the service instance can be reused by the next caller. (In almost all cases there’s a better way to solve this problem, but WCF allows it).
I’m sure there are additional use cases.
I have recently come across the term Instance Deactivation.
a) What is that?
b) What for we need that?
c) In what context will it be useful?
I am looking for a simple answer that can be easily undestandable and if posible with some pseudo code.
Thanks
When a WCF method is invoked, it is passed to a service instance.
Instance Deactivation simply refers to the moment where the WCF system disposes of this instance.
In a Per-Call Service, instance deactivation will occur after each method call.
In a Per-Session Service, instance deactivation will occur when the client calls Close on the proxy, or when the transport-session's inactivity timeout is reached.
In a Singleton Service, instance deactivation will occur when the Service Host is closed.
You can also configure individual service methods to trigger instance deactivation:.
[OperationBehavior(ReleaseInstanceMode = ReleaseInstanceMode.AfterCall)]
public void MyMethodWhichTriggersAnAutomaticRelease()
{
// ...
}
As well as this, you can manually trigger a service instance release:
public void MyMethodWhichTriggersAManualRelease()
{
OperationContext.Current.InstanceContext.ReleaseServiceInstance();
}
Juval Lowy has this to say on whether you should manually override the standard instance deactivation mechanisms:
Instance deactivation is an
optimization technique, and like all
optimization techniques, you should
avoid it in the general case. Consider
using instance deactivation only after
failing to meet both your performance
and scalability goals and when careful
examination and profiling has proven
beyond a doubt that using instance
deactivation will improve the
situation.
Basically I take to mean that the instance of the class that the service operation is being called on is not torn down. If you have per call activation then a new instance of the service class will be created each time you call an operation on the service. After the method ends then that instance of the class will be disposed.
If you want to improve performance say at the expense of scalability then you would not deactivate the instance and thus choose a different instance activation scheme.
This MSDN artice : Discover Mighty Instance Management Techniques For Developing WCF Apps together with the link in #SteveCav answer provide good references.
I have a WCF service which is a singleton and which manages a collection of proxies to another WCF service which is session-based. The singleton creates a new proxy and passes it some work to do, and the session-based service makes calls back to the singleton service when certain activities complete (pretty much all of the OperationContract methods are one-way). The typical completion path is that the singleton receives an event from a hardware device when the process is complete, and it calls a method on the session-based service which returns the final status, and then disposes of its proxy. When an error situation is encountered and the session-based service can't continue with what it needs to do, I need to make a call back to the singleton to let it know to dispose of the proxy associated with that instance. However, to make the WCF method call back to the singleton, I need to create a proxy back to the singleton. What I'm seeing happen is that the singleton disposes of its proxy as expected, but every time the proxy to the singleton that the session-based service created times out when I try to dispose of it. Since the session ends with that method call and the instance will be disposed of, does it matter if the proxy it created doesn't get properly disposed?
Disposing of a WCF service is not the same as disposing of any other object that implements IDisposable. It is ok to dispose of the service when it is in a good state but when a fault occurs the dispose method will throw another exception.
Some insight is here and perhaps use the WCFProxyGenerator but I have not tried it
Not sure exactly the problem with the session based service and whether it is different from the WCF service.
My recommendation is not to use a singleton but use Dependency Injection to give the class that uses the WCF service a factory so when it wants the service it can create it. And when a fault occurs it can throw away the old and create a new one. Without seeing some code it is hard to see if this is possible.