What is Instance Deactivation in WCF? - wcf

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.

Related

What are the differences between BackgroundServices and SingletonServices?

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.

Communication between two WCF service libraries on the same Windows Service host

The project I'm currently working on includes a server that receives C# scripts (partial code) from clients, wraps it to create a complete class, compiles it then load it into a separate AppDomain for execution.
A task (currently running script) can send feedback to the user at any point of it's execution, as defined in the script by the user. And possibly the task might wait for a response from the user (currently assuming it's only right after having sent feedback). And the user might, at any moment, decide to kill a task.
The server is implemented as a Windows Service hosting a WCF Service Library.
As I don't want to overcomplicate the client to make it communicate directly with the dynamically created AppDomains, the (partial) solution that I considered after some research was hosting a second WCF service with named pipe binding to make the dynamic AppDomains use it as a relay between them and the client facing WCF service.
My issue is that now I can't think of a clean way to have the two WCF services interact.
My ideas are:
Having them maintain direct references to each other:
Seeing as Normally both of the services are singletons it shouldn't be hard to do.
But that would be a pain to maintain in the case one of them fails and needs to be restarted. (I'm still new to WCF so I have no idea how common that is, but it's still an issue to consider. I think.)
Introducing some sort of a "message queue" (or two, one for each direction) with properties that can be set and subscribed to. Thus when one service sets a property an event will be triggered in the second. But that feels somewhat hacky to me, even though I can't really think of any clear issues.
I could really use some expert input on what I'm trying to accomplish, be it opinions on my thoughts or new ideas. Even if that involves rethinking the architecture. This project is still in an early enough stage to afford some rework, as long as there is enough reason to do that of course.
Since I've put lots of efforts (read: 2 minutes on paint) to prepare a quick (read: useless) schema of the system, I'll link it here since I don't have the reputation to post images:
Link to schema
Edit:
As I now have the reputation thanks to an upvote:
Still after rereading my question, I feel that perhaps I have been looking at this issue from a too narrow perspective by thinking of the services as something more special than ordinary classes. The more I think about it the more I feel that the observer pattern is probably the best approach to take.
Just for the record, and to avoid leaving my (silly) question unanswered, I've realised that I was looking at this too narrowly by trying to find a solution specific to WCF services.
And finally I ended up using a variation of the observer pattern (based on the IObservable<T>Interface).
I came across the same issue. The way I handled a duplex communication between the two servers is as following:
For each process (AppDomain Seperated Task) create a pair of WCF services. Both services have their Instancing set to PerSession (no need for singleton which may cause problems in the long run like disconnect). This means the Client will be communicating for each process (AppDomain Separated Task) with two distinct Service instances or a service pair (i.e. Service1 and Service2).
We want a duplex communication in between these two services, which means that both can communicate with the other and pass data (in the form of a DataContract class object).
For this:
1- Declare two services (i.e. in a separate class library) and host them (self hosting or else).
2- Create your DataContract class and add any property, collection, enum etc. as you like. Both services must have a get-set property for this class.
3- In the same class library (where the Service1 and 2 classes reside), create another class. This class will act as a depository for the Service pair instances. It has a static List in order to register the service pair instances (you can identify each service with a GUID).
4- We setup the client proxy using svcUtil.exe (or by code). When the client makes a service request, a service (i.e. service1) will be created by the WCF. At service1, create or launch the process (App Domain Separated Task) as client2 and at its constructor create the Service2 proxy by code.
5- Initialize the Service2 instance (i.e. by a call to the service2) and register the service pair instances at static list of the depository (so that it can be retrieved later for duplex communication). Now we have both service instances and both of them are registered as a pair into a static list.
6- Start communication between both services by making a call from Client1 proxy.
7- At Service1 call method, retrieve the service pair from the static list. Deep copy (DeepClone) the Datacontract class object from Service1 to the Service2 using the get-set property mentioned at (2). (Note that you can use one of the many Deep Clone libraries from Nuget like DeepCloner).
8- Make a call back from Service2. Client2 now has the identical DataContract class property values as Client1
9- Repeat steps 6-8 for Client2 proxy for Service2-Service1 communication.

Context and Instance in WCF

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.

WCF Named Pipe IPC

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.

How does WAS/IIS manage ServiceHost instances?

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.