Singleton pattern for the web

I

INeedADip

I want to get some feedback so don't hold back.

I have a webservice that is responsible for Formatting a ton of information
that is then queried by other applications (agents) that utilize it (the
info).
All this "formatting" and logic I am talking about needs to be done in a
centralized place and accessed by the agents. That is why we chose to go
with a web service.

Now...all this formatting needs to be done and held in memory so the agents
don't have to wait for it.
So we decided to implement a sort of singleton pattern...what do you guys
think?
Here is some sample code:

public class TheManager
{
private static object lockObject = new Object();
private const string CACHE_MANAGER = "Cache:Manager";
private List<InfoPacket> _preparedPackets;

private TheManager() { initFunction(); }

public static InfoPacket GetInfoPacket() {
getManager().getInfoPacket(); }

public InfoPacket getInfoPacket() { ......some code ..... return
this._preparedPackets[0] }

private static TheManager getManager()
{
object o =
System.Web.HttpContext.Current.Application.Get(CACHE_MANAGER);
TheManager = oManager;
if(o == null)
{
lock(lockObject)
{
o =
System.Web.HttpContext.Current.Application.Get(CACHE_MANAGER);
if (o == null)
{oManager = new TheManager();
System.Web.HttpContext.Current.Application.Add(CACHE_MANAGER,oManager);}
else oManager = (TheManager)o;
}
}
else oManager = (TheManager)o;

return oManager;

}

}

So now in our web service (*.asmx) we can call TheManager.GetInfoPacket()
and a prepared packet is returned. Again, this is just a snippet of the
code..so we have functions and threads that are preparing the packet. We
are very consious of threading (utilizing lock() where needed). It has
performed VERY well and everything seems to be going as planned.

What do you guys think of a Singleton-esk pattern like the one above?
 
I

INeedADip

I didn't mean to type "TheManager = oManager";
I meant "TheManager oManager;" Just declaring the object..
 
J

Jon Skeet [C# MVP]

INeedADip said:
I want to get some feedback so don't hold back.

What do you guys think of a Singleton-esk pattern like the one above?

I think that double-checked locking is a bad idea in general. Unless
you know the exact characteristics of the cache - and in particular,
whether or not it places any memory barriers around access - the code
you provided *may* not be thread-safe.

See http://www.pobox.com/~skeet/csharp/singleton.html for more
information about this.

I'd just always lock before getting it out of the cache. I don't
believe you'd even be able to measure the difference in performance,
and it would be safer.

Jon
 
G

Guest

Any ideas on how to write trace information from a singleton to trace.axd
file? I have a singleton that is instantiated in the application start event
that I cannot for the live of me figure out how to send trace output to the
web trace file.

Thanks and cheers!
 
N

Nicholas Paldino [.NET/C# MVP]

INeedADip,

You did ask for honesty, so here you go =)

I do think your public and private naming conventions need some work.
Having a class called "TheManager" is superfluous. You can drop the "The".

Also, while your private implementation details are private, I don't
like the casing or use of the getManager and getInfoPacket methods. They
should be properties. The only reason they should be methods is if they are
doing significant work justifies a method call (prefixed by "Get")
indicating that it is a significant operation. If they truly should be
methods, then the method names should be capitalized.

But that's just my personal view. I do understand that there are naming
conventions for private code for companies, and that stuff does not change
easily or overnight. However, I do think that private implementation
guidelines should mimic the public naming conventions (which you are
adhering to pretty well it would seem).

As for the real meat and potatoes, why are you storing the singleton in
the Application? Application is just a class derived from the
NameObjectCollectionBase class in the System.Collections.Specialized
namespace.

Why not just implement a regular singleton (using the guidelines that
Jon pointed out, if you need lazy-load semantics)? After all, the
Application state is only applicable for the app domain on the local machine
(i.e. your web app), and a regular singleton would work just fine in this
scenario.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

INeedADip said:
I want to get some feedback so don't hold back.

I have a webservice that is responsible for Formatting a ton of
information that is then queried by other applications (agents) that
utilize it (the info).
All this "formatting" and logic I am talking about needs to be done in a
centralized place and accessed by the agents. That is why we chose to go
with a web service.

Now...all this formatting needs to be done and held in memory so the
agents don't have to wait for it.
So we decided to implement a sort of singleton pattern...what do you guys
think?
Here is some sample code:

public class TheManager
{
private static object lockObject = new Object();
private const string CACHE_MANAGER = "Cache:Manager";
private List<InfoPacket> _preparedPackets;

private TheManager() { initFunction(); }

public static InfoPacket GetInfoPacket() {
getManager().getInfoPacket(); }

public InfoPacket getInfoPacket() { ......some code ..... return
this._preparedPackets[0] }

private static TheManager getManager()
{
object o =
System.Web.HttpContext.Current.Application.Get(CACHE_MANAGER);
TheManager = oManager;
if(o == null)
{
lock(lockObject)
{
o =
System.Web.HttpContext.Current.Application.Get(CACHE_MANAGER);
if (o == null)
{oManager = new TheManager();
System.Web.HttpContext.Current.Application.Add(CACHE_MANAGER,oManager);}
else oManager = (TheManager)o;
}
}
else oManager = (TheManager)o;

return oManager;

}

}

So now in our web service (*.asmx) we can call TheManager.GetInfoPacket()
and a prepared packet is returned. Again, this is just a snippet of the
code..so we have functions and threads that are preparing the packet. We
are very consious of threading (utilizing lock() where needed). It has
performed VERY well and everything seems to be going as planned.

What do you guys think of a Singleton-esk pattern like the one above?
 
I

INeedADip

I agree with you on the naming conventions.....I just typed that stuff out
to get the "Singleton" point across. Those aren't the actual names of the
classes...I also agree with the Property vs. Method statement (like we have
implemented). And I have now moved my "lock(lockObject)" per Jon's
suggestion.

My question was more about the Singleton-esk thing we have going..
You ask why we are storing the object in the Application State, but what is
another option?

As I understand it (probably wrong), the cache is per worker process...so
their could be more then one. And since the web service calls are
stateless, I thought we would need to store this in the Application State.

You said "a regular singleton would work just fine in this scenario"...but I
don't see how. I am not that experienced in Web Services, I tend to think
of them more like stateless aspx pages...Please let me know what you have in
mind...maybe we are going the wrong direction.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top