views:

46

answers:

2

I'm working on a new website, written in VB.Net using ASP.NET MVC2, there is a need to call "legacy" VB6 code for various complex bits of business logic. The VB6 is a framework consisting of many dlls and is very stateful, we are pretty much emulating how the framework is used in our client application, ie the application runs (lots of state setup), a user logs on (even more state) and then loads a file (even more state).

I've been provided with a "web service interface framework" to get this up and running for use in the web app, this "web framework" hides the legacy code behind a thin layer running under IIS. The idea being that thread pooling provided by IIS will reduce memory use etc etc. I can't help but believe that the guy who provided this has missed the point, since each instance is so stateful there is no way that a thread pool can work, since once a user logs on using one particular object from the pool, no other object will be capable of servicing that client (since it wont have the state)! Also, adding a web service interface and associated SOAP marshalling is a huge overhead compared to calling the objects directly.

The only way I can think of doing this is either a single legacy interface instance which is used by all clients and blocked by each call until it completes, or a thread per client with each legacy interface object being created in a new thread and living for the life of the client.

None of these is ideal but with the amount of code in question and the prolonged migration programme to .net (2+ years and still stateful) I can't think of an alternative. We run the original client app in a citrix environment for some customers so I expect that it could also run ok with thread per client given a beefy enough server and that the overheads of the framework itself should be lower than when the client app is involved.

Any ideas??

A: 

Here's an option but it won't be pretty.

It sounds like you need to associate a long lived object (the stateful object to your backend tier) with individual users.

You could store this object in Application state and associate it with the users Session state with a key. You'd need to provide a wrapper to keep track of them all. When the session dies you could capture the event and destroy the backend object.

Application state is a key/value store just like Session. You can access through HttpContext.Application

The big downfall to this is that the objects you put in there stick around until you destroy them so your wrapper and session destroying code need to be spot on. Other than that this might be a quick way to get up and running.

Like I said, it won't be optimal, but it'll probably work.

More info on implications: http://msdn.microsoft.com/en-us/library/bf9xhdz4(VS.71).aspx

EDIT:

You could also make this work in a web farm environment. Store the information needed to recreate your stateful legacy object in Session state which can be shared between the machines using the built in SQL Provider. If a user bounces to a server where the object doesn't exist your Application state wrapper can just recreate it from the Session state info.

This just leaves how to clean up the stateful object on servers where it isn't needed. In your retrieval wrapper update a hashtable or something with the access time each time the given stateful object is accessed. Have a periodic cleanup routine in th wrapper detroy the stateful objects that haven't been accessed since a little more than the session timeout value of your web app.

jwsample
I don't think reconstructing state is possible due to the level of global variables in use, so my only option is to store an object per user in application or session, but I assume I would need to ensure each object is created on a seperate thread to keep the globals apart from each other? Any reason I would use Application rather than Session since it's a session level thing?Thanks
Rob
I just meant store whatever variables you need to make a new object for the user if they get bounced to a different server. Also, this is why I would do the separation between App and Session state. Session state can be serialized and shared between multiple machines if need be but the back end object most likely can't. So if I get transferred to the new machine I still have my session state (user name, password, etc.) to create a new back end object to shove into application state on the new machine.As far as creating on different threads I don't think you need to worry about it.
jwsample
A: 

I suggest that you take a look at this framework Visual WebGui. I am an employee with this company and therefore wouldn’t sound objective but I believe Visual WebGui had solved some of the major issues with scaling statefull applications and turning single user environment into multi user environment. Worth a look.