471,319 Members | 1,940 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,319 software developers and data experts.

Singleton pattern for the web

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(CAC HE_MANAGER);
TheManager = oManager;
if(o == null)
{
lock(lockObject)
{
o =
System.Web.HttpContext.Current.Application.Get(CAC HE_MANAGER);
if (o == null)
{oManager = new TheManager();
System.Web.HttpContext.Current.Application.Add(CAC HE_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?
Jan 23 '06 #1
7 5615
I didn't mean to type "TheManager = oManager";
I meant "TheManager oManager;" Just declaring the object..
Jan 23 '06 #2
INeedADip wrote:
I want to get some feedback so don't hold back.
<snip>
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

Jan 23 '06 #3
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!

"Jon Skeet [C# MVP]" wrote:
INeedADip wrote:
I want to get some feedback so don't hold back.


<snip>
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

Jan 24 '06 #4
If you use the HttpContext.Current property, this gives you access to the
current HttpContext, which gives you access to the Trace class:

HttpContext ctx = HttpContext.Current ;
ctx.Trace.Write ("Yo, It's me!");

Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"asapjim" wrote:
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!

"Jon Skeet [C# MVP]" wrote:
INeedADip wrote:
I want to get some feedback so don't hold back.


<snip>
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

Jan 24 '06 #5
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]
- mv*@spam.guard.caspershouse.com

"INeedADip" <IN*******@gmail.com> wrote in message
news:ee**************@TK2MSFTNGP15.phx.gbl...
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(CAC HE_MANAGER);
TheManager = oManager;
if(o == null)
{
lock(lockObject)
{
o =
System.Web.HttpContext.Current.Application.Get(CAC HE_MANAGER);
if (o == null)
{oManager = new TheManager();
System.Web.HttpContext.Current.Application.Add(CAC HE_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?

Jan 24 '06 #6
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.
Jan 24 '06 #7
Still looking for constructive comments or and explination of what
Nicholas Paldino meant. How could a regular singleton work here? I
thought the stateless nature of ASP.NET (web and web services) would
prohibate using a regular singleton....

I've posted this on my blog to collect more comments:
http://ineedadip.blogspot.com/2006/0...rn-on-web.html

Jan 29 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Alicia Roberts | last post: by
4 posts views Thread by Neil Zanella | last post: by
3 posts views Thread by Alicia Roberts | last post: by
11 posts views Thread by Daniel Billingsley | last post: by
13 posts views Thread by Robert W. | last post: by
2 posts views Thread by Kevin Newman | last post: by
3 posts views Thread by dischdennis | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.