Creating a connection (object) pool - any libraries to use? - c#

We have a 3rd party piece of software that uses a bunch of internal middleware and services to connect to outside databases. Through this API I only have a bit of information on the connection object it uses when contacting an Oracle DB.
Update: This isn't a pooling to connect to Oracle. This is a pool of objects/connections to a piece of software that deal with massive amounts of statistical data which in turn has it's own connections to Oracle. The reason we need pooling is this software can be accessed 50-200 times a second, and it can takes over 20 seconds to instantiate the Initiate object.
What I'm wondering is if .NET has any classes I can inherit / use to help me build a better object pooling system than what is currently written. I have no problem writing my own, but I'd rather not re-invent the wheel if I could inherit from one.
Note, this is pretty much object pooling, but the objects have the ability to connect.
Update:
The current system works once the pool is created. It has a worker thread that ensures the pool is clean and working. The problem comes in when the Application gets no activity for a long time. When a request comes in, the system looks for a connection and they're all cleaned up (I believe because the cache is gone). So it regenerates them, but this can take upwards of 1 minute to do the 100+ connections, and the request can time out due to this being accessed through SOA.

You can implement your own using Object Pool Design pattern:
http://sourcemaking.com/design_patterns/object_pool
or use this one:
C# Object Pooling Pattern implementation

Related

Entity Framework Database Connection in Single-Threaded Application

I have a unique (or so I think) problem - we have an ASP.NET web app using MVC principles. The project will be at most single threaded (our business requires single point of control). We are using Entity Framework to connect to the database
Problem:
We want to query our database less frequently than every page load.
I have considered putting our database connection in a singleton but am worried about connecting to in too infrequently -- will a query still work if it connected a significant time ago? How would you recommend connecting to the database?
How would you recommend connecting to the database?
Do NOT use a shared connection. Connections are not thread-safe, and are pooled by .NET, so creating one generally isn't an expensive operation.
The best practice is to create a command and connection for every database request. If you are using Entity Framework, then this will be taken care of for you.
If you want to cache results using the built-in Session or Cache properties, then that's fine, but don't cache disposable resources like connections, EF contexts, etc.
If at some point you find you have a measurable performance problem directly related to creating connections or contexts, then you can try and deal with that, but don't try to optimize something that might not even be a problem.
If you want to get data without connecting to the database, you need to cache it - either in memory, in a file or in whatever mean of storage you want, but you need to keep it in front of the DB somehow. There is no other way known to me.
If by connecting you mean building a completely new SqlConnection to your DB, then you can either rely on connection pooling (EF is smart enough to keep your connections alive for some minutes even after you finish your business) or you can just create connections and keep them alive inside your application by not closing them instantly (i.e. keeping track of them inside a structure).
But you should definitely consider if this is REALLY what you want. The way EF does it internally is most of the time exactly what you want.
Some further reading:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

Right way of using WCF service client [duplicate]

This question already has answers here:
Best Practice for WCF Service Proxy lifetime?
(4 answers)
Reuse of WCF service clients
(2 answers)
Closed 9 years ago.
I have a UI application in which I consume a WCF service like this
public MainWindow()
{
....
mServiceClient = new ServiceClient("EndPointTCP");
}
Should I create the client as a member of class and close the client along with exit of my application or Should I create a new client whenever its required in a method and close there itself.
It depends solely onwhat you want to achieve. There is no "best way to do it" since both ways are possible, good, and have different tradeoffs.
Holding the clientobject simply wastes resources. It also may leak context data between calls. You might have a bug that will cause mClient.Buy(100) and mClient.Sell(100) to work properly when used alone, but fail when used together mClient.Buy(100); mClient.Sell(100). Dropping and re-creating fresh instance each time could save you from that one bug, but obviously that's not a good argument for it.
Recreating the client each time a call is to be made has however the vague benefit of .. having a fresh client every time. If your app has a possibility to dynamically change the endpoint during the app's runtime, then automatically your client will be always using the newest addresses/logins/passwords/etc.
However, not recreating the client object at every time is simply faster. Mind that it's WCF layer, so the actual underlying connection can be any. Were it some protocol with heavy setup with some keyexchange, encryption, etc, you may find that creating a new client every time might create a new connection at every time and it will slow down eveyrthing, while keeping the instance will work blazingly fast, since connection might be kept open and reused. Often you try to keep the connection when you have to perform many and often calls to the service, like 24h/day twice/sec monitoring some remote value for breaching safe limits.
On yet the other hand, you might not want the connection to linger. Your remote service may have thousands of clients and limited resources, so you might want to close the connection ASAP so others may connect. Often you'd do it like that when the calls to the service are really rarely done, only once in a time, ie. when user clicks after returning from coffe break.
Please don't get me wrong: all above is just conjuring some vague "facts" from a void. I do not know your app, nor your service, nor your bindings (sans "endpoint TCP"). The most important factors are all on your side and they sit in the actual way how your app and that remote service work and interoperate. If you care about what you ask, you must first simply research the topic on your side. Best - simply try both ways and check if it works and how does it perform. The difference would be something like 2..6 lines of code, so that's, well, rather quick.
There are already some similar questions:
Reuse of WCF service clients
Reusing a WCF service client or creating one each time?
In my opinion it depends on your application type (scalability, performance requirements, ...) but usually I think that it's more safe to recreate the ServiceClient each time. In this way you don't need special code if there are connections problems between requests and with the latest version of WCF seems that there isn't a big performance impact.
See http://msdn.microsoft.com/en-us/library/aa738757.aspx.
Consider also that ServiceClient is not thread safe (at least reading MSDN).

Optimizing SQl connections

I have noticed that it takes a long time in connecting to the database when executing my query. Is it possible to write an asp.net application in such way that has a database connection that is always open? Or is it better to write service and have asp.net app communicate with that service?
You can use connection pooling in order to conserve time it takes to initialize a connection. BTW, SQL-Server supports it OOTB, so you don't really have to implement it yourself.
It does not matter much which means you use to connect to the DB (ADO.NET, DAAB, etc..)
As to your second suggestion, to write a service and have the application communicate requests to it: it wont help in this scenario, since you are simply moving the problem to another process, but the accumulated time of fulfilling a request remains or even grows, considering the extra network time.

WCF Per Call Services with Shared Business objects

I would need some help to point me in the right direction.
We want to expose service functionality (which consists of reading + updating a SQL Server database) via WebHTTP end points as per-call services to users.
We don't want to use SOAP if avoidable, as we have trouble to make this interoperate on other platforms.
This must be scalable to 1000+ users, which, in this scenario, are unlikely to submit many concurrent requests. It is estimated that at any given time there should be max 25 concurrent requests.
(That's why per-session services were ruled out, since that would meant to keep 1000+ sessions open while only 25 actions are performed.)
By experience with a test service, we find however, that using pure Per-Call WCF services over HTTP perform poorly, with the largest time lapse being the initialization of the SQL server connection.
It's sort of a similar scenario to what a web server normally would encounter.
Therefore it appeared sensible to use a similar approach as web servers do - for performance reasons they keep a pool of HTTP engines active, and incoming requests are being assigned one of the engines in the pool.
So we want to keep a pool of 25-30 "Business Logic Objects" (i.e. classes with the actual service logic decoupled from mere service interfaces) open which should be instantiated when the service host starts.
Seems that WCF does not have a scenario built in which supports this out of the box.
How would I go about it?
When I am self hosting, I can derive a custom class from ServiceHost and add a Dictionary with the Business objects. This would incur threading issues I guess, which I would have to handle with manual synchronization, correct?
If we decide to host in IIS, how would I do it then, since IIS automatically takes care of creating an instance of the ServiceHost class, and thus I have not much of a chance to throw my own custom host in-between, do I?
Or is this a bad approach altogether. Any other ideas appreciated.
Is there actually a bottleneck with the stateless, session-free approach?
The pool of "business logic objects" doesn't look like a good idea to me. You'll face hard-to-debug concurrency issues.
Have you actually tested the following pattern?
one business logic object per request, shortest lifetime as possible
one SQL connection per business logic object
stateless services
By experience with a test service, we find however, that using pure
Per-Call WCF services over HTTP perform poorly, with the largest time
lapse being the initialization of the SQL server connection.
Really, the SQL server connection shouldn't be a bottleneck because of SQL Server connection pooling.
I dont think their would be much cost associated with instantiating business logic object. you may enable pooling on sql connection object as pointed by ken. Better to go for caching business object rather pooling business logic object.

Tibco EMS Session sharing Connection object

Our connectivity to EMS code was initially ill-designed and created one TopicConnection object per topic that we listened to. So, in effect, whenever we subscribed to a topic, we create a new connection, a new session and, lastly, a new listener.
We would like to switch to a single connection model. Although I am able to do this easily in our code by sharing one connection object and creating a new session object per topic, we are unsure whether this is going to cause any issues without code.
My understanding is that the Tibco EMS client library is thread safe with regards to sharing a connection. In effect, a connection is just a pipe and the sessions can resuse the this pipe in a thread safe manner.
Is this assumption correct or is there more to this?
The .NET EMS API is based on JMS. In JMS, the Connection and Session objects are specified to be thread-safe and can be reused within the program. You are quite correct in that the Connection object simply represent a network pipe to the EMS server. The EMS User's Guide states:
A connection is a fairly heavyweight object, so most clients will create a connection once and keep it open until the client exits. Your application can create multiple connections, if necessary.
And regarding sessions:
A Session is a single-threaded context for producing or consuming messages. You create Message Producers or Message Consumers using Session objects.
Essentially, unless you need very large volumes and are bumping into performance limitations, it's perfectly safe to use just one connection in your application. The session controls the transaction/acknowledgement semantics of any producers or consumers created within, but is again safe to reuse. I would probably use separate sessions for modules exist within the application with distinct life cycles (think separate deployment units within an application server).
Your EMS server installation will contain a samples directory with various code (something like C:\tibco\ems\5.0\samples\cs). The code in csTopicSubscriber.cs shows how to write a single-threaded topic consumer. There is no multi-threaded topic consumer example but csMsgConsumerPerf.cs demonstrates how to do it with queues.
Be sure to clean up any objects you create after you're done with them - e.g. close the topic consumer object, the session, and the connection when you're finished. Leaking handles without closing them can result in unpredictable behaviour when combined with prefetch and fault-tolerant reconnect settings.
I think yes as long as sharing is within the same application (exe, binary).
We have shared same connection object, and used it as a singleton in our code.
Agree with an earlier answer: the JMS Session must not be shared between threads, but the Connection can/should be. So one connection per application is ok (make sure you start/close it only once - best before/after the individual threads creation).
And then create and use one Session per thread. Remember that when you close() a Session, it will block until all receive callbacks have really returned. So do NOT call close() from within a callback's onMessage().

Categories