The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Singleton on Web Server

So, we've got this nice object we call the "DataEngine" that encapsulates all data access for a particular application.

The app is a simple desktop app that happens to do a lot of data acces, and we've partitioned off the data access and encapsulated all the database functionality in the DataEngine object. This object happens to implement the Singleton pattern for various reasons that I don't care to go into here -- suffice it to say that it's a singleton and will stay that way.

Fact: I don't do web programming. "We" do web programming, but I do databases. I don't do web programming. It's 5:00 AM. The folks that know of these things are not hanging around the office at the moment, so I have no one to answer my question.

There's an extension to this application that's bound for a moderate sized development effort in exposing some of the desktop app's functionality via a public web server. The functionality included in the DataEngine would be ReallyNiceToHave on the web server, and I'd like to simply drop the .dll on the web server and start using it.

Here's my question(s): As a Singleton, won't all the user sessions be hitting the same object -- e.g. all web page hits that use the DataEngine will be routed to the single Singleton object. If so, then I'm concerned about the DataEngine being "thread-safe". It's not. If I start locking things up to make it thread-safe, I'm worried it will become a huge bottleneck as folks pile up waiting for their turn in the DataEngine.

Am I making sense on this? Is there a way around my above outlined concerns? Please understand, I'm the DataBaseGuy, and not the WebGuy, and I'm not really sure if my concerns are even valid at this point.

Discussion ... Anyone(?) ... Anyone(?) ... Beuler(?) ...
Thursday, May 12, 2005
Depends on whether the singleton is thread-safe.
Colm O'Connor Send private email
Thursday, May 12, 2005
One singleton will exist per app domain - not per session - so you do have a problem.

Short of rewriting it to remove the singleton-ness :) you're going to have to get control of the app domain instantiation. The first thing that comes to mind is ugly - write a wrapper object that creates the singleton in a new app domain for each call. This is going to hurt performance of course. I would rather rewrite the singleton - or make it thread safe.

Adding thread safety may not be a big problem - depends on how active the site is. And "thread safe" doesn't always mean using locks - you can avoid the use of shared data as well.

If anything else comes to mind, I'll post it a little later.... 5AM??? Get some sleep man. :)
Jeff Mastry Send private email
Thursday, May 12, 2005
Short answer is...if you're not sure its thread safe, it probably isn't.

Long answer - if the "Data engine" is really just a bundle of SQL calls, you just need to make sure that each user gets a different connection.

Let the database deal with contention and locking for you.

To make sure this will scale, use connection pooling on the web server (not sure about your tech environment, but its pretty straightforward in .NET, Java, and I think even the MS data access components directly support pooling if you're on Windows).

If you've got a bunch of business logic and SHARED state in your singleton, then you may need a "pool" of those instead (which will make it not a singleton anymore).

Good luck.
Dave C Send private email
Thursday, May 12, 2005
I didn't see any environment in your post so it's hard to say.

If it's java or C++ then the singleton is naturally global. .Net has app domains but i don't know much about that.

For thread safety you need see if it matters. If the DataEngine is a thin wrapper for another library then you may be ok.

If you just make stuff thread safe then you will likely keep locks open too long and open yourself up to deadlock.

You can have the singleton be per thread so work in the same thread wouldn't need locks. Depending on your app organization this may or may not work.

You could queue up requests to the engine so it is still single threaded.
son of parnas
Thursday, May 12, 2005
I had a previous gig where they wanted something like this. I ended up writing an NT Service that was also an ActiveX component. There were a couple other reasons why it had to be a service (project requirements), and was hairy enough that I don't think I'd want to do another (debugging/troubleshooting was a pain, especially with a sysadmin who didn't want to let me have any rights to do anything on the box).
Thursday, May 12, 2005
You could also take the COM+ route and build it as a serviced component. Then COM+ will take care of the syncronization details for you (via your configuration).

But that route brings in a whole lot of other crap you probably don't want to deal with.
Chris Tavares Send private email
Saturday, May 14, 2005
Thanks all for your suggestions. Here's the route we've decided on: Remove all "stateful" objects from the DataEngine. The DE is still there, with all the basic functionality, but instead of handling the data access itself, it will pass back objects to its clients that will handle their own data acess via these objects. That way, the DE is only creating objects and passing them back to the callers. The caller is then responsible for using those objects (that are no longer associated with the DE) to get at the data they need.

This is the route that appears will cause the least amount of change to the basic structure and functionality of the DE (read that as "will cause us the least pain for the most benefit".

Thanks for the suggestions.
Saturday, May 14, 2005
actually, singleton's are only global to the parent classloader.  That may not mean anything to anyone, but it caused me to be confused as hell for a week.
Vince Send private email
Thursday, May 19, 2005

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz