views:

969

answers:

3

In a ASP.NET application that I am writing I need to use connections to a specific server (something like a DB but... different). The connections are quite expensive to establish (a few seconds, literally) so I'm trying to write a pool to improve scalability.

Everything is pretty simple, up to one point - recycling old connections. With old I mean "connections that have been in the pool unused for longer than, say, 5 minutes". Cleaning them up would also free up resources on the server that they connect to.

I would need some kind of thread that wakes up every 5 minutes, checks for old unused connections in the pool, and closes them. However, as I've come to understand from Google, ASP.NET and long-running threads don't mix.

I'm not afraid of the whole process being terminated, because then my pool would get cleaned up too (destructors and all). What I am afraid of is that my cleanup thread might be terminated before my application terminates (and my pool is left without a cleaner). Or the other way round - that my cleaning thread blocks my application from closing.

How to implement this correctly?


Several people have suggested an external service that would do this. I will elaborate on the "mysterios service" so that you can see why this is not feasible.

The "mysterious service" is a behemoth of an application that has been written by my company for over 10 years. It is a Delphi accounting application that uses MSSQL or Oracle for its data. There is no other server.

Recently (as in a few years ago) it also acquired an interface that external applications can use to communicate with it. It is windows console application that is basically the same application, except instead of GUI it listens to a socket and uses some kind of Delphi serialization to pass data forth and back.

On the client side there is a .DLL (written in Java, later modified to compile under J#) which parses this binary data stream and mimicks the business layer in .NET. That is - I get all the same business classes (700+) as in the original application in Delphi. Or something pretty close to that (I think the application itself has >3000 classes). And I have to use them to do whatever business logic I want. All my calls get forwarded to the real application which then does the work.

I cannot connect directly to the MSSQL/Oracle DB, because there is a lot of bizzare business logic in the server that I would then have to replicate and keep up with (the application is constantly being developed). I cannot recreate the client .DLL, because that would be too time-consuming, and the protocol would dictate nearly the same result anyway. I cannot write a wrapper around it, since I would have to wrap all the 700+ classes that are in there.

In other words - I'm not in control of the business layer. It is as it is (and actually several people have quit rather than continue working with it). I'm just trying to make the best of things.


To Chris and other curious people.

The code to use the stuff is something like this:

ConnectionType con = new ConnectionType;
con.OpenConnection("server", "port", "username", "password");
BLObjectNumber234 obj = (BLObjectNumber234)con.GetBLObject("BLObjectNumber234");
obj.GetByPK(123);
// Do some stuff with obj's properties and methods
// that are different for each BLObject type

These BL objects are pretty haphazard. They are all singletons - The call to con.GetBLObject always returns the same instance. Most of the data is obtained as a DataTable by calling a special method, but quite a few are also in properties; some require calling special methods with bizzare undocumented constants; there are also properties that are othe BL object instances (not sure whether those are singletons too, I think not) and those require special code to populate, etc.

All in all, I'd call the system "patchware" - since it seems like it has been made by a million patches and workarounds all sticked together in whatever way had been most convenient at the time.


Bump? (how do you do bumping here anyway?)

A: 

You could write a WCF service that wrappers the service you are trying to call and then communicate with this mysterious service only through your WCF service application.

WCF has various models to handle pooling and cleanup.

Chris Simpson
+1  A: 

You would not need to wrapper every class and function, just the actions that you need to perform. So you might need a method to fetch some data and a method to update some data, this would translate in the service as a series of calls to the various functions as required. The front-end logic would be simplified and therefore this would simplify future releases of the web site.


Ok, just to address your own addition to this question - I think you are getting too hung up on the meaning of "wrapper". I would hope that you are already doing some sort of wrappering anyway, or perhaps I need to stop assuming this and ask you the question directly: Are you calling this service directly from the code behind the asp.net pages, or have you built separate classes to handle the communication between the front end and the service? Once we establish the architecture you currently have we will see whether it is feasible to move this logic to a separate service (and then reap the benefits that WCF can offer).

Chris Simpson
+1  A: 

I agree with Chris, it would be much more appropriate to have all your business logic (the code that communicates with all the mysterious business objects) in a separate layer than the web (presentation) layer.

That would make your application design much more scalable and you would be able to do things like pooling, threading and other scalability-related tasks much easier.

If you choose to use WCF to communicate between the web and the business layer (use names pipes if it's on the same machine) you get yourself a clean, scalable and performant architecture.

JacobE