Related
I am posting this question using an automatic translation.
Please forgive any grammatical errors.
I have built an application using the .NET framework and the ASP.net Web API.
I have split the virtual path for each customer region within a site running on IIS and copied the same binary to run as separate applications.
The applications run in the same application pool.
Recently, some customers have been making a very large number of requests in a matter of minutes.
(I suspect a glitch in the system on the customer's end).
I am thinking of adding a static class to my current application that keeps track of the number of requests per customer in a given time period and blocks them if the threshold is exceeded.
From past StackOverFlow articles I have found that "information in the static class is lost if the application pool is recycled", but I have determined that this is not a problem in this case.
For my purposes, I only need to be able to retain information for a few minutes.
However, I still have a few questions that I can't find answers to, so I'd like to ask you all a few questions.
Even if the same binary is running in the same application pool, will the static class information be kept separately for different applications?
Will the static constructor of a static class be executed even after the application pool is recycled?
Is there a problem if I reference a field in Global.asax from within a static class?
Is there a problem with referencing the contents of web.config from within a static class?
Attached below is the source of my experimental implementation.
I plan to call the static method "ExcessiveRequestCheck.isExcessiveRequest" of this static class after the Web API receives the request and identifies the user ID.
Any advice would be sincerely appreciated.
P.S.
I understand that this approach does not work well in a load balancing environment. Currently my system only runs on one virtual machine. If you are moving to the cloud or deploying a load balancer, you will probably need a different approach than this one.
public static class ExcessiveRequestCheck
{
private static Dictionary<string, ExcessiveRequestInfo> dicExcessiveRequestCheckInfo = new Dictionary<string, ExcessiveRequestInfo>();
private static object initLock = new object();
private static object dicExcessiveRequestCheckInfoLock = new object();
//If possible, I want this process to be a static constructor
public static Dictionary<int, int> dicExcessiveRequestSkipConditions
{
get
{
lock (initLock)
{
if (ExcessiveRequestCheck._dicExcessiveRequestSkipConditions == null)
{
//if possible, I want to set this value from Web.config.
ExcessiveRequestCheck._dicExcessiveRequestSkipConditions = new Dictionary<int, int>() {
{ 5, 3 }, { 15, 5 }, { 45, 10 }, { 120, 20 }
};
}
return ExcessiveRequestCheck._dicExcessiveRequestSkipConditions;
}
}
}
private static Dictionary<int, int> _dicExcessiveRequestSkipConditions = null;
public const int BUFFER_CLEAR_MINUTES = 5;
public static bool isExcessiveRequest(string userId)
{
ExcessiveRequestCheck.refreshExcessiveRequestCheckInfo();
lock (ExcessiveRequestCheck.dicExcessiveRequestCheckInfoLock)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.ContainsKey(userId) == false)
{
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.Add(userId, new ExcessiveRequestInfo() { countRequest = 1 });
return false;
}
bool doSkip = false;
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].countRequest++;
foreach (KeyValuePair<int, int> pair in ExcessiveRequestCheck.dicExcessiveRequestSkipConditions)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].lastRequesttTime.AddSeconds(pair.Key) > DateTime.Now)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].countRequest > pair.Value)
{
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].wasRequestSkip = true;
doSkip = true;
}
}
}
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].lastRequesttTime = DateTime.Now;
return doSkip;
}
}
public static void refreshExcessiveRequestCheckInfo()
{
lock (ExcessiveRequestCheck.dicExcessiveRequestCheckInfoLock)
{
var keyList = ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.Keys;
foreach (string key in keyList)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.ContainsKey(key))
{
var value = ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[key];
if (value.lastRequesttTime.AddMinutes(BUFFER_CLEAR_MINUTES) < DateTime.Now)
{
if (value.wasRequestSkip)
{
//this NLog instance was created in Global.asax.cs
WebApiApplication.logger.Fatal("skip request! user id=" + key);
}
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.Remove(key);
}
}
}
}
}
}
class ExcessiveRequestInfo
{
public DateTime requestStartTime { get; set; } = DateTime.Now;
public DateTime lastRequesttTime { get; set; } = DateTime.Now;
public int countRequest { get; set; } = 0;
public bool wasRequestSkip { get; set; } = false;
}
Your questions
Even if the same binary is running in the same application pool, will the static class information be kept separately for different applications?
Yes, they are separate
Will the static constructor of a static class be executed even after the application pool is recycled?
Yes, the static constructor is guaranteed to be called before any of the static methods are executed
Is there a problem if I reference a field in Global.asax from within a static class?
No more than accessing it from anywhere else
Is there a problem with referencing the contents of web.config from within a static class?
No more than accessing it from anywhere else
Your general approach
DoS
If you're trying to mitigate a denial-of-service attack or credential stuffing attack, your approach probably won't work, since requests to your service will still result in load being added to your server, and if they are performing a credential stuffing attack, it'll fill up your dictionary with millions of entries and possibly cause your application to crash.
If you want to mitigate a denial-of-service attack effectively, you will probably need a more network-oriented solution, such as a smart firewall or a WAF.
Rate limiting
If on the other hand you are attempting to throttle specific users' activities (i.e. rate limiting), again, your approach probably isn't the greatest, because it does not support load balancing-- your list is held in in-process memory. For per-user rate limiting you will probably need to track user activity in a central data store accessible to all of your servers.
Static constructors
As a general rule, you should try to avoid static constructors, or keep them very simple, as a failure in a static constructor will cause your entire application to fail to start. Be careful!
even if the same binary is running in the same application pool, will the static class information be kept separately for different applications?
If by different applications, you mean separate web sites? yes, it will be kept separate to each web site you have running for that app pool.
Will the static constructor of a static class be executed even after the application pool is recycled?
Hum, that's a bit confusing. The constructor will only be executed if you call the class and that given constructor. Since there is never a instance of the class created, then the "initialize/new" event is never used nor triggered. So, any method with parameters will run and work fine - including the constructor. I would suggest that there is not some "event" that gets triggered on first use - it would not and does not make sense in the context of a static class, since you never create an instance. So, if you have some methods with parameters then fine.
So, constructor in the context of new instance of the class makes no sense - (did not even think that is possible with static).
There is no concept of "new" event that triggers, so I fail to see how this issue can ever matter.
Is there a problem if I reference a field in Global.asax from within a static class?
Well, values in that class are global to ALL users. But, those values can go out of scope just about any old time you please. As a result, ZERO use of public members is practial. While a app-pool re-start will re-set those class values? They can go out of scope just about any old time. They are global to all and every user. So, persisting values, or attempting to persit values in a static class is NOT a viable choice for production code. You can have methods (code) in that class, but any public persisting values really can't be relied upon to persist correctly. I'm not 100% sure, but even just general .net garbage collection would likely cause a re-set.
If you need this information to persist, then you can't use static, you have to create a instance of that class and persist it in session(). And session is per user.
A static class public values will apply to EVERY user - not just the current user. In effect those values are global to all users - but without any real ccontrol or garrutee that the values will persit - you have no control over this and thus you can't adopt this concpet and design for any system of practial value.
Is there a problem with referencing the contents of web.config from within a static class?
Reading values? No problem. Update or modify values? - a MASSIVE different issue. You modify web.config, that will trigger a app pool restart.
So, you free to read any file - text files, xml or whatever, and that includes web.config. As long as you not modify such files, then no problems.
The main issue here?
It simple not practical to assume, or build a design in which public static class values are to persist. The ZERO control you have when such values may go out of scope is somthing you have ZERO control over, and thus such designs can't use nor rely on values persisting.
And of course on many web hosting systems? They are now adopting cloud computing. This means from one post back to the next, you might be using a different server, and again, that means such values can't persist in memory, since from one post-back to the next, or one web service call to the next? You may well be hitting a different server anyway (and they don't share memory) (so, this suggests say using SQL server based sessions, or at the very least persisting such values in a database).
In fact, if you need such persisting values and data? Then use a database. The WHOLE idea of web based software is you do NOT have state between post-backs. And you are attempting to go even down a worse road, but hope on a wing and a prayer that some global values "might" and "sort of" and "maybe" will persist between calls to the web site.
Answer:
You really can't do this with any realm of reliably.
So, most of your questions don't really matter. What matters is these values are to persist, and you can't rely on such a design. If you need some persisting values, then you have to adopt a system and design that supports that concept (viewstate, cookies, or session()).
Now, I suppose you can give this a try, and then come back with a detailed report and how your experience turned out. But, there are too many pit falls, and without any code or system control over persisting values in memory, I don't think I would go down this road.
In web land, it makes next to no sense to have public variables that you attempt to persist in a static class. You can have code, you can have cool methods, you can use session(). But, the concept of persisting values in static class is a design choice that does not make sense, and can't be relied upon.
Web software is assumed to be state-less, and that VERY much is the assumption you have to make in regards to a static class, or in fact general use of such code.
What is the best way to initialize static fields via a static init method and afterwards make sure that the method is never called again? (no more than once during the lifetime of the program)
This is an example of what I currently thought of, it seems pretty simple to me but I couldn't find any examples of similar patterns that deal with this:
class Entity
{
static Manager manager;
static bool isInitialized;
public static void Initialize(Manager manager)
{
if (isInitialized)
throw Exception("Class Entity already initialized."
+ "Do not call Entity.Initialize() twice.");
isInitialized = true;
Entity.manager = manager;
}
}
What is the best way to initialize static fields via a static init method and afterwards make sure that the method is never called again?
Do you really have to do this? Why do you not want to create an instance of Manager and make it available to code which relies on it through dependency injection? That would make your code much cleaner:
You'd allow it to be testable with different initialization paths
You wouldn't need any checking for "bad" duplicate initialization
You wouldn't need to structure your calling code to specify a single initialization point for this class. (You may need to do something similar for the IoC container of course...)
You'd allow your code which depends on it to be more testable too
The code which depends on Manager would be express that dependency in a clearer way
I suspect you haven't found any similar examples because it's an anti-pattern.
If you do go for your current approach, you should really try to make it thread-safe, too...
Don't over think it, if that pattern works for you, go with it. There isn't always a "right" answer, and trying to stick to rigid patterns and practices just for the sake of sticking to them is not a good idea either. IMHO.
Sorry for stating the obvious, but you could use the object initializer or the static constructor. Besides that, you can just not call the method. Seriously. Why would someone call a method called initialize anyway.
What you could do is this. You can hide the method from IntelliSense and similar with this attribute. Stops it from cluttering up the dropdown too
Your implementation is not thread-safe, but is otherwise reasonable. If it's intended for use in a multithreaded environment, add locking.
In your sample, the open question is what should happen if multiple callers (possibly from multiple threads) call the initialization method with different parameters. This is what makes your pattern unusual, and prevents you from using the obvious static constructor or object initializer.
Can't you just use a static constructor?
Of course, you do not have control over when this constructor is called, but don't know if this is a requirement.
http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx
You might want to use a singleton pattern with parameters to only expose certain functionality of the Manager variable.
class Entity
{
private Manager _manager = null;
public Manager manager
{
get
{
return _manager;
}
set
{
if (manager == null)
{
_manager = value;
}
}
}
/* rest of class */
}
Now you can use the manager object as any variable, but repeated sets will not modify the value.
this.manager = new Manager(0); // sets the manager
this.manager = new Manager(1); // does nothing
Now to complete the pattern in your constructor somewhere or at some reset function you might want to do a
this._manager = null;
Hi
I am developing a web site
I have a class which is the connection to data base
The class consists a methods that write and read from the data base
Currently, the class is static and also its methods
I call the class from web pages like that:
//mydbClass is the name of the class , not an object
mydbClass.getUserName(userID)
The question is:
Do I need to create a class object, so that each time user asking for a page
a new object is created and it communicates with the data base , like that:
mydbClass mydb = new mydbClass();
mydb.getUserName(userID)
Because if I do not create a new object
So all the users that read or write to the data base
Will use the same static object, then it will be very busy and perhaps it will collapse
I'd love an answer
Thanks
micha
If you want to keep using your class a bit like a static class but with a state , you can implement the singleton pattern
http://en.wikipedia.org/wiki/Singleton_pattern
public class mydbClass{
private static mydbClass _current = new mydbClass();
public static mydbClass Current{
get{
return _current;
}
}
private mydbClass(){}
public User getUserName(userid){
//be sure to create a new connection each times
}
}
The advantage here is that you can simply implement interface in this class, break dependencies and then mock it for testing purpose.
Anyway, you'll always have to create a new connection at each request do not create a static connection object.
You definitely should not use a static class for the connections. If you use a static class then you have to worry about being thread safe because of all the threads using the same class to talk to the database. Just create new database connections each time, and use connection pooling. Connection pooling will make creating new connections each time much faster.
It depends on what you're doing inside the methods.
If, within the method, you open a new connection, use it, and dispose of it, you're fine. No harm, no foul. So long as you're not maintaining state, you're good to go.
On the other hand, if you're maintaining state, you've got problems, as thread-safety enters the picture. In that case, you're much better off just creating a class that's designed to be instantiated.
I would advice static class, if you see small number of concurrent users querying the Static class.A static class can easily handle sufficient requests serially (say a 20 + in a second).
The database routine is more likely bottleneck, depending on the query.
Take care of thread safety**
i'm working on a fork of the Divan CouchDB library, and ran into a need to set some configuration parameters on the httpwebrequest that's used behind the scenes. At first i started threading the parameters through all the layers of constructors and method calls involved, but then decided - why not pass in a configuration delegate?
so in a more generic scenario,
given :
class Foo {
private parm1, parm2, ... , parmN
public Foo(parm1, parm2, ... , parmN) {
this.parm1 = parm1;
this.parm2 = parm2;
...
this.parmN = parmN;
}
public Bar DoWork() {
var r = new externallyKnownResource();
r.parm1 = parm1;
r.parm2 = parm2;
...
r.parmN = parmN;
r.doStuff();
}
}
do:
class Foo {
private Action<externallyKnownResource> configurator;
public Foo(Action<externallyKnownResource> configurator) {
this.configurator = configurator;
}
public Bar DoWork() {
var r = new externallyKnownResource();
configurator(r);
r.doStuff();
}
}
the latter seems a lot cleaner to me, but it does expose to the outside world that class Foo uses externallyKnownResource
thoughts?
This can lead to cleaner looking code, but has a huge disadvantage.
If you use a delegate for your configuration, you lose a lot of control over how the objects get configured. The problem is that the delegate can do anything - you can't control what happens here. You're letting a third party run arbitrary code inside of your constructors, and trusting them to do the "right thing." This usually means you end up having to write a lot of code to make sure that everything was setup properly by the delegate, or you can wind up with very brittle, easy to break classes.
It becomes much more difficult to verify that the delegate properly sets up each requirement, especially as you go deeper into the tree. Usually, the verification code ends up much messier than the original code would have been, passing parameters through the hierarchy.
I may be missing something here, but it seems like a big disadvantage to create the externallyKnownResource object down in DoWork(). This precludes easy substitution of an alternate implementation.
Why not:
public Bar DoWork( IExternallyKnownResource r ) { ... }
IMO, you're best off accepting a configuration object as a single parameter to your Foo constructor, rather than a dozen (or so) separate parameters.
Edit:
there's no one-size-fits-all solution, no. but the question is fairly simple. i'm writing something that consumes an externally known entity (httpwebrequest) that's already self-validating and has a ton of potentially necessary parameters. my options, really, are to re-create almost all of the configuration parameters this has, and shuttle them in every time, or put the onus on the consumer to configure it as they see fit. – kolosy
The problem with your request is that in general it is poor class design to make the user of the class configure an external resource, even if it's a well-known or commonly used resource. It is better class design to have your class hide all of that from the user of your class. That means more work in your class, yes, passing configuration information to your external resource, but that's the point of having a separate class. Otherwise why not just have the caller of your class do all the work on your external resource? Why bother with a separate class in the first place?
Now, if this is an internal class doing some simple utility work for another class that you will always control, then you're fine. But don't expose this type of paradigm publicly.
I'm looking at using a singleton in a multithreaded Win service for doing logging, and wanted to know what are some of the problems I might encounter. I have already set up the get instance to handle syncing with
private static volatile Logging _instance;
private static object _syncRoot = new object();
private Logging(){}
public static Logging Instance
{
get
{
if (_instance==null)
{
lock(_syncRoot)
{
if (_instance == null)
{
_instance = new Logging();
}
}
}
return _instance;
}
}
Is there anything else I might need to worry about?
That looks pretty good to me.
See Implementing the Singleton Pattern in C# for more info.
Edit: Should probably put the return inside the lock, though.
This is more informational than anything else.
What you've posted is the double-checked locking algorithm - and what you've posted will work, as far as I'm aware. (As of Java 1.5 it works there, too.) However, it's very fragile - if you get any bit of it wrong, you could introduce very subtle race conditions.
I usually prefer to initialize the singleton in the static initializer:
public class Singleton
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance
{
get { return instance; }
}
private Singleton()
{
// Do stuff
}
}
(Add a static constructor if you want a bit of extra laziness.)
That pattern's easier to get right, and in most cases it does just as well.
There's more detail on my C# singleton implementation page (also linked by Michael).
As for the dangers - I'd say the biggest problem is that you lose testability. Probably not too bad for logging.
Singleton's have the potential to become a bottleneck for access to the resource embodied by the class, and force sequential access to a resource that could otherwise be used in parallel.
In this case, that may not be a bad thing, because you don't want multiple items writing to your file at the same instant, and even so I don't think your implementation will have that result. But it's something to be aware of.
You need to ensure that each method in the logger are safe to run concurrently, i.e. that they don't write to shared state without proper locking.
You are using double-checked locking what is considered a anti-pattern. Wikipedia has patterns with and without lazy initialization for different languages.
After creating the singleton instance you must of course ensure that all methods are thread-safe.
A better suggestion would be to establish the logger in a single-threaded setup step, so it's guaranteed to be there when you need it. In a Windows Service, OnStart is a great place to do this.
Another option you have is to used the System.Threading.Interlocked.CompareExchange(T%, T, T) : T method to switch out. It's less confusing and it's guaranteed to work.
System.Threading.Interlocked.CompareExchange<Logging>(_instance, null, new Logging());
There is some debate with respect to the need to make the first check for null use Thread.VolatileRead() if you use the double checked locking pattern and want it to work on all memory models. An example of the debate can be read at http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/b1932d46-877f-41f1-bb9d-b4992f29cedc/.
That said, I typically use Jon Skeet's solution from above.
I think if Logging instance methods are thread-safe there's nothing to worry about.