Suggestion required to achieve caching functionality in WCF - wcf

I’ve a WCF service which is used to get some data from my database. Size of database is very large approximately 2 GB. So I cache this data. I want when service host this data should be cached so I firstly used
InstanceContextMode = InstanceContextMode.Single
This Service Behviors allows me that I can simply write caching code in service constructor, as constructor will only be invoked when servicehost.open (); method call. Whenever client will call this service through proxy constructor will not invoked. This works very fine. Later I realized that this InstanceContextMode has performance issue when 1000 users call this service at a time, because only single instance of this service serves the all requests. To get maximum performance I changed my settings to
InstanceContextMode = InstanceContextMode.PerCall
with
ConcurrencyMode = ConcurrencyMode.Multiple
Now I want to get the same caching feature that is when service host data would be cached. Please help me to solve this problem.
Please do let me know either through CustomBehaviors I can achieve this?
Regards,
Rizwan

Combination of InstanceContextMode.PerCall with ConcurrencyMode.Multiple doesn't make sense. PerCall instancing creates new service instance for each request. Multiple concurrency mode allow service instance to handle multiple parallel requests. How can service instance which is created only to handle single request (PerCall) be used to handle parallel requests (Multiple)?
I think the problem which occured by calling your singleton service (I believe that you also used ConcurrencyMode.Multiple) with 1000 concurrent users is simply based on the fact that server doesn't have performance to deal with so many concurrent users or the service code / caching is not optimized. This will not be solved by using PerCall instancing.
Anyway if you want to share some cache among multiple PerCall instances of the service you have to create some well known object representing your cache - use singleton pattern or service locator. This object will handle caching and concurrent access from service instances.

Related

Call "AddScoped" within / inside "AddTransient" in DotNet Core?

I do have basic understanding between AddTransient Vs AddScoped Vs AddSingleton. I know how these 3 behave individually but I am not sure if we can call these 3 instance types within each other and if YES then how my application will behave in that scenario?
I tried reading couple of blogs online but couldn't get answer to this specific case. I am not sure if it's possible to call these instance within each other or not possible at all?
Thanks.
A long Lifetime service cannot request a shorter Lifetime service..
Because during its lifetime, several short-term services may change, and it would not be correct to randomly select any of them.
Singleton cannot consume a Transient or Scoped Service.
A Transient service can consume any of the three.
A Scoped service can consume any of the three.
A Transient injected into a Scoped service takes on the lifetime of the Scoped service.
Within a scope, multiple Transients of the same type that depend on Scoped services will get new instances of the Transient service, but the same instance of the Scoped service will be injected into each.
And, of course, any Transient or Scoped service that depends on a Singleton service will always receive the single instance of that service.

Initialize expensive resource at start up of WCF service hosted in IIS

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.

How can I get Entity Framework and WCF to work with transactions? Okay...what's the secret?

I've been trying several different ways in order to get a simple set of transactions to work for a simple WCF client/server situation. My WCF server has a class level declaration of the Entity Framework class for my database access and several methods to modify data and a method to SaveChanges. I'm using the Oracle Data Access (ODP.NET).
For instance I want to call a modification from the client and then a separate call to save the changes in the WCF service. It doesn't work. Basically, everything executes fine, but when the second call to save the changes is made, the WCF service no longer has the original context and therefore no changes are saved (and, consequently, the previous call that made the changes was automatically rolled back).
I'm utilizing Transaction scope around both operations in my client and executing Complete() after done. My WCF services have OperationContract's that use [TransactionFlow(TransactionFlowOption.Mandatory)] and those method implementations use [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]. Finally, my web config is configured with a wsHttpBinding that has the transactionFlow property set to True.
I'm having no luck. No matter what I try, when I try hitting the service for the follow-up save, the EF context is already renewed.
This has nothing to do with transaction. Transaction works on transactional resource but without calling SaveChanges in the first request there was no transactional resource active because EF context is not part of the transaction - the database is and the database is affected only when you call SaveChanges. To make this work you don't need distributed transactions. You need session-full service and store the EF context in the service instance. It a client uses the same client proxy instance to communicate with the service for all requests the communication will be handled by the same service instance = same EF context instance which will remember changes from previous calls.
IMHO this is very bad architecture. Simply don't use it. Expose specialized methods on WCF service which will do changes and save them. If you need to execute these methods in transaction with other transactional resources use the real distributed transaction.
this might be a reason. Since your are making an update in the different context. context doesn't know that the object is update to have say the context that the object is modified and then you call savechnages(). See if it helps

WCF Service vs. Referenced Component?

We have a multi services application.
We have moved a method that involves a DB access to a separate component that is exposed by a WCF endpoint.
We have more than one service that need to use this method.
The dilemma is what to use:
A WCF call to the method.
Call directly to the method, resolved by our DI engine.
The system performance is a critical issue.
So what do you think is better?
Using WCF to make the cal
Reference the required service and call it in-process using the DI engine.
Thanks Or.
If performance is critical, referencing the service component and calling directly the DB without going through all the WCF layers and serialization processes will be faster but less robust. If you decide to change the implementation you will need to recompile the client application as well. My advice would be to measure the performance of the WCF service call and if you are happy with the results leave it that way.

How to return HttpContext.Current.Cache from WCF?

I have a WCF service hosted in IIS and want to return the data which is reside in the cache of IIS (HttpContext.Current.Cache)
What is the most appropriate choice of type this service should return?
If I were you, I would not rely on the fact that the service is hosted in IIS. What if you wanted to host your WCF service with some other technology? I think you should check out memcached which is a much more general caching solution, and it works fine with .NET.
Anyway, if you really want to use the IIS cache, use System.Web.HttpRuntime.Cache instead of HttpContext.Current.Cache as the HttpContext is not always available.
Also, as cruizer said, the actual type of your objects is totally irrelevant as long as they are serializable (that is, the classes are decorated with the [Serializable()] attribute). The IIS cache itself does not require serializable objects but WCF does.
You serialize your objects in order to transport them, but there's no need to cache serializable objects.
Your service calls your business logic in order to process the requests but what gets over the wire should not be your business objects but your service's data contracts.
Wrap your cache API and decouple it from the HttpRuntime Cache. As DrJokepu said, access asp.net cache through HttpRuntime.Cache if you choose so.
whatever type you stored in the cache of course...it should be serializable though