10

I'm having an issue with the Singleton pattern.

It is really weird, but it looks like there are two or three instances of my Singleton Pattern. My website, is an actions site, with timers and I'm handling those timers and prices with my Singleton Object.

What is happening is that some people see some prices, and other people see other prices always when they are in different networks.

For example, In my office, my people see some auction at 0.56 cents, everybody sees the same, but in another network, for example, my house, I see 0.55 cents and also the timers have different values.

Having said this, I've tested my Singleton, by generating a GUID and logging it in my log file. Here is some code

public class Singleton
{
    private static Singleton instance;
    private static System.Threading.Mutex mutex;

    System.Guid token;

    private Singleton() { 
        token = System.Guid.NewGuid();
        Logger.Log("New singleton Instance" + token.toString());
    }
    static Singleton()
    {
        instance = new Singleton();
        mutex = new System.Threading.Mutex();
    }

    public static Singleton Acquire()
    {
        mutex.WaitOne();
        return instance;
    }

    // Each call to Acquire() requires a call to Release()
    public static void Release()
    {
        mutex.ReleaseMutex();
    }

    public void SomeAction()
    {
       Logger.Log(token.toString() + " - SomeAction");
    }
}

In this code, I generate the token on the constructor, and log the creation of a new Singleton, then... in the SomeAction method, I log who is doing that action.

After this, we made a couple of tests and downloaded the log file.

To my surprise, I see only one "New Singleton Instance bla" which is correct. but then, many calls to the SomeAction Method with different GUIDs, which is weird.

I checked that object is only created in the static constructor, and I also checked that there is no manual creation anywhere.

For more information, this only happens on my production server, which is a goDaddy hosting. I've asked if there is more than one application pool for my website and they say there is only one app Pool.

Ram
  • 3,092
  • 10
  • 40
  • 56
varholl
  • 331
  • 1
  • 14

5 Answers5

4

Your singleton lifetime is tied to the current worker process of IIS.

If you have multiple worker processes configured then not all of the requests are handled by the same process and thus not the same singleton.

Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
  • This makes sense, i will check how many worker processes do I have... In case I have more than one, do you know how can I share the same singleton instance? Is it possible? – varholl Dec 05 '11 at 13:58
  • This is definitively my problem, as there are more than one worker process I have more than one singleton object... The sad thing is that I can't use any sync method since I can't use Message queue or remoting... I'm trying to see If i can sync every 5 seconds but In some cases... that is too much time to wait :( – varholl Dec 06 '11 at 12:40
2

I can't say for sure that this is your problem, but it might be worth checking:

  • If you create an instance before your logging framework is initialised, does the message get cached, or just thrown away? I've seen log messages go missing in the past because they happen before logging is initialised.
  • Is it possible you are referencing multiple versions of the assembly containing this class? This could cause one instance of the class per assembly version to be created, so the values seen would depend on the code calling it. However this would not explain the behaviour you see of different values when accessing the same pages from different geographical locations.
  • I would also be tempted to log some form of unique machine id if you can, to verify that there is only one copy of this code running on one machine. "Trust nobody, prove everything" is a very useful heuristic when trying to understand obscure behaviours.
Community
  • 1
  • 1
Theo Spears
  • 151
  • 3
  • Thanks for your reply! I will check the log initialization, it could make sense to lose those messages because of that. Is it possible to have more than one version of the same dll in the bin directory? I mean I have all my dlls on my bin folder not the GAC. – varholl Dec 05 '11 at 13:59
  • I believe it is possible to load multiple versions of the same assembly from the same directory, but it takes a bit of trickery around renaming files, so you are unlikely to have done it by accident. – Theo Spears Dec 05 '11 at 16:39
1

Your web site may only be using one application pool, but an application pool may spawn more than one host process. Check the number of worker processes for your application pool.

Polyfun
  • 9,479
  • 4
  • 31
  • 39
1

The issue could be that your singleton pattern you have implemented is not thread safe. because in a web app you got more than one thread running at the same time(worker processes) it could happen that two thread create two different instance of your class. You should also consider where your web app is running on. If you have deployed your web app on a web-farm it could happen that different web server got a different instance of your class as a static variable "live" in the memory of the web server.

Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
  • Thanks for your reply, in my log file, i see different thread Ids sharing the same token, So I don't think it is a thread issues.. also I make sure to be thread safe by using locks and mutex almost everywhere! anyways I will check further to make sure it is thread safe – varholl Dec 05 '11 at 13:56
  • check also if the web app is deployed on a web-farm. In this case you will have an instance for each web server – Massimiliano Peluso Dec 05 '11 at 13:58
0

It seems that your static constructor doesn't check to see if the instance has already been created. Something like:

static Singleton()
    {
    if (instance == null)
        {
        instance = new Singleton();
        mutex = new System.Threading.Mutex();
        }
    }

should ensure that the other methods in the class are actually using the same "instance" of instance.

Dan
  • 114
  • 2
  • 9
  • 4
    -1: This is a [static constructor](http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29.aspx). It is executed only once... – Daniel Hilgarth Dec 05 '11 at 13:41
  • Again: Static constructors are only executed once. – Felix K. Dec 05 '11 at 13:41
  • A static constructor (http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29.aspx) is only executed once. Please take a look at Jon Skeet's article about implementing Singletons (http://www.csharpindepth.com/Articles/General/Singleton.aspx). – Christophe Geers Dec 05 '11 at 13:42