For a project I am working on I’m implementing a class as a singularity. The class is responsible for detecting what stage (Dev, Test, Production, etc.) the system is running in, and returning certain values accordingly so our dev team won’t have to worry about handling staging settings every time they use those values. In addition, it allows us to override what the stage is currently, for the purpose of pretending to be in a different stage.
My concern has to deal with how the singularity will behave when multi-threading is involved. The code below outlines the basic setup that will be used.
My question is, if program & program2 could be running on different threads at the same time, will the OverrideStage() function (which changes a private variable in the instance) interfere with the other program’s expected behavior?
Example:
1) Program starts, sets stage to DEV
2) On another thread, Program2 starts, sets stage to PRODUCTION
3) Back in Program, try to get a value, will the value be in DEV or PRODUCTION?
namespace TESTING
{
class Program
{
static void Run()
{
Staging stage = Staging.Instance;
stage.OverrideStage(Staging.DEV);
SqlConnection connDev = new SqlConnection(stage.ConnectionString("example")); // Connection to development database
// Do Stuff
stage.EndOverride();
SqlConnection connBackToAuto = new SqlConnection(stage.ConnectionString("example")); // Connection to detected stage database
}
}
class Program2
{
static void Run()
{
Staging s = Staging.Instance;
s.OverrideStage(Staging.PRODUCTION);
SqlConnection connDev = new SqlConnection(s.ConnectionString("example")); // Connection to production database
// Do stuff
s.EndOverride();
}
}
} // End namespace
I guess the question can be simplified to:
Are s and stage the same instance of Staging?
I don’t believe your application can have two main entry points… what you’re describing is not feasible, unless you specify multiple entry points.Now, if it were feasible (i.e. you specified multiple entry points), then
Your attempt to change the
Stagingmode will result in updating the mode for both program instances.So let’s look at your example:
The value will most likely be
PRODUCTION, however it may not be the case depending on how the threads started. It can get complicated, because if both threads are started relatively quickly one after the other, then the stage might beDEVorPRODUCTIONdepending on when the context switch happened between the two threads.Update 1.0
Since strike out the multiple entry points because you’ve substituted
Mainmethods withRunmethods.Update 2.0
To Singleton or not to Singleton
The situation you’re describing is very confusing, mainly because a Program usually contains the
Mainentry point for your application. Under normal circumstances, one would expect that the program either runs inDEVorPRODUCTIONmode. Running multiple program instances in separate threads and in different modes is very confusing!!! I can’t think of a realistic example where anybody would want to do that.Let’s suppose there was such an obscure example tho: your best bet is to provide each program with its own internal staging state, rather than a global (Singleton) staging state. This guarantees that you can start multiple instances of your program in multiple threads and each one would run independently of each-other. You generally want to share as little between threads as possible- some people refer to it as shared nothing architecture.
What’s the staging mode?
If you take the Singleton approach, then this question becomes very difficult to answer.
Program2waits forProgramto get initialized (via some sort of thread signalling mechanism), then you’re guaranteed that the mode will bePRODUCTION.DEVorPRODUCTIONdepending on many issues.You can, indeed, create a separate
Stagingclasses in different namespaces and each one is used depending on the mode you’re utilizing. However, that is no different than maintaining two separate Staging classes i.e.DevStagingandProductionStaging. You generally want to avoid coding the same thing twice, so this option is starting to look less and less desirable.In general, the issue of knowing which staging mode you’re currently in is actually not so much to do with threading, the problem is just magnified when threading is involved. The reason why your
Stagingmode will change is because both programs use the same staging instance, which is provided to them by the Staging (singleton) instance.