Say you have an Action in ASP.NET MVC in a multi-instance environment that looks something like this*:
public void AddLolCat(int userId)
{
var user = _Db.Users.ById(userId);
user.LolCats.Add( new LolCat() );
user.LolCatCount = user.LolCats.Count();
_Db.SaveChanges();
}
When a user repeatedly presses a button or refreshes, race conditions will occur, making it possible that LolCatCount is not similar to the amount of LolCats.
Question
What is the common way to fix these issues? You could fix it client side in JavaScript, but that might not always be possible. I.e. when something happens on a page refresh, or because someone is screwing around in Fiddler.
I guess you have to make some kind of a network based lock?
Do you really have to suffer the extra latency per call?
Can you tell an Action that it is only allowed to be executed once per User?
Is there any common pattern already in place that you can use? Like a Filter or attribute?
Do you return early, or do you really lock the process?
When you return early, is there an 'established' response / response code I should return?
When you use a lock, how do you prevent thread starvation with (semi) long running processes?
* just a stupid example shown for brevity. Real world examples are a lot more complicated.
Answer 1: (The general approach)
If the data store supports transactions you could do the following:
using(var trans = new TransactionScope(.., ..Serializable..)) {
var user = _Db.Users.ById(userId);
user.LolCats.Add( new LolCat() );
user.LolCatCount = user.LolCats.Count();
_Db.SaveChanges();
trans.Complete();
}
this will lock the user record in the database making other requests wait until the transaction has been committed.
Answer 2: (Only possible with single process)
Enabling sessions and using session will cause implicit locking between requests from the same user (session).
Session["TRIGGER_LOCKING"] = true;
Answer 3: (Example specific)
Deduce the number of LolCats from the collection instead of keeping track of it in a separate field and thus avoid inconsistency issues.
Answers to your specific questsions:
I guess you have to make some kind of a network based lock?
yes, database locks are common
Do you really have to suffer the extra latency per call?
say what?
Can you tell an Action that it is only allowed to be executed once per User
You could implement an attribute that uses the implicit session locking or some custom variant of it but that won't work between processes.
Is there any common pattern already in place that you can use? Like a Filter or attribute?
Common practice is to use locks in the database to solve the multi instance issue. No filter or attribute that I know of.
Do you return early, or do you really lock the process?
Depends on your use case. Commonly you wait ("lock the process"). However if your database store supports the async/await pattern you would do something like
var user = await _Db.Users.ByIdAsync(userId);
this will free the thread to do other work while waiting for the lock.
When you return early, is there an 'established' response / response code I should return?
I don't think so, pick something that fits your use case.
When you use a lock, how do you prevent thread starvation with (semi) long running processes?
I guess you should consider using queues.
By "multi-instance" you're obviously referring to a web farm or maybe a web garden situation where just using a mutex or monitor isn't going to be sufficient to serialize requests.
So... do you you have just one database on the back end? Why not just use a database transaction?
It sounds like you probably don't want to force serialized access to this one section of code for all user id's, right? You want to serialize requests per user id?
It seems to me that the right thinking about this is to serialize access to the source data, which is the LolCats records in the database.
I do like the idea of disabling the button or link in the browser for the duration of a request, to prevent the user from hammering away on the button over and over again before previous requests finish processing and return. That seems like an easy enough step with a lot of benefit.
But I doubt that is enough to guarantee the serialized access you want to enforce.
You could also implement shared session state and implement some kind of a lock on a session-based object, but it would probably need to be a collection (of user id's) in order to enforce the serializable-per-user paradigm.
I'd vote for using a database transaction.
I suggest, and personally use mutex on this case.
I have write here : Mutex release issues in ASP.NET C# code , a class that handle mutex but you can make your own.
So base on the class from this answer your code will be look like:
public void AddLolCat(int userId)
{
// I add here some text in front of the number, because I see its an integer
// so its better to make it a little more complex to avoid conflicts
var gl = new MyNamedLock("SiteName." + userId.ToString());
try
{
//Enter lock
if (gl.enterLockWithTimeout())
{
var user = _Db.Users.ById(userId);
user.LolCats.Add( new LolCat() );
user.LolCatCount = user.LolCats.Count();
_Db.SaveChanges();
}
else
{
// log the error
throw new Exception("Failed to enter lock");
}
}
finally
{
//Leave lock
gl.leaveLock();
}
}
Here the lock is base on the user, so different users will not block each other.
About Session Lock
If you use the asp.net session on your call then you may win a free lock "ticket" from the session. The session is lock each call until the page is return.
Read about that on this q/a:
Web app blocked while processing another web app on sharing same session
Does ASP.NET Web Forms prevent a double click submission?
jQuery Ajax calls to web service seem to be synchronous
Well MVC is stateless meaning that you'll have to handle with yourself manually. From a purist perspective I would recommend preventing the multiple presses by using a client-side lock, although my preference is to disable the button and apply an appropriate CSSClass to demonstrate its disabled state. I guess my reasoning is we cannot fully determine the consumer of the action so while you provide the example of Fiddler, there is no way to truly determine whether multiple clicks are applicable or not.
However, if you wanted to pursue a server-side locking mechanism, this article provides an example storing the requester's information in the server-side cache and returns an appropriate response depending on the timeout / actions you would want to implement.
HTH
One possible solution is to avoid the redundancy which can lead to inconsistent data.
i.e. If LolCatCount can be determined at runtime, then determine it at runtime instead of persisting this redundant information.
We need a screenshot of our app for a unit test. CaptureScreen() and CopyFromScreen() somehow ignore the app and return pictures of an empty desktop. So we wrote this to fake a PrtScn keystroke:
public static Bitmap GetAltScreenshot()
{
Clipboard.Clear();
SendKeys.SendWait("{PRTSC}");
while (!Clipboard.ContainsImage())
{
Thread.Sleep(500);
}
return new Bitmap(Clipboard.GetImage());
}
Alt isn't part of the keystroke, so this should return a bitmap of the entire screen. Yet somehow this snippet returns just the focused window. Which is fine, that solves our problem - but we don't understand how.
Why does this return a shot of just the focused window, instead of the entire monitor?
There is in fact a "reason", turn to the MSDN Library article that documents the key abbreviations you can use. Note the entry for PRINT SCREEN:
{PRTSC} (reserved for future use)
The is a somewhat clumsy way of saying "We know it doesn't work, maybe will fix that some day". That day hasn't yet arrived. So you are probably testing the failure mode of this key and actually like the way it works. This is of course not healthy, they may actually fix the problem some day and break your program.
Do note the Note about the <appSettings> entry that you can add to your .config file, further down that same MSDN page. I suspect, but do not know for a fact, that the SendInput method is more reliable.
I'm trying to detect if our application is running from a DVD (because this disables/enables functionality in the logic). So far I've come up with the code snippet below that seems to work, though I was really wondering if there's a best-practice in detecting this.
public static bool IsDVDInstallation()
{
try
{
string location = Assembly.GetExecutingAssembly().Location;
var info = new DriveInfo(Path.GetPathRoot(location));
return info.DriveType == DriveType.CDRom;
}
catch
{
return false;
}
}
If you want to know if the application (rather than whatever particular assembly you're in) is running on an optical drive, then you probably should use GetEntryAssembly() rather than GetExecutingAssembly(). Other than that, your logic above seems perfectly reasonable.
Why the silent catch block? Did you get an exception when trying this before? Even if you did, you really should capture the specific exceptions that you know how to handle rather than everything.
Your solution is about as solid as it gets. However it will still function if running from a Virtual DVD Drive (which I assume you don't want)
In which case you'd have to query WMI to get more information on the hardware to try and figure out if it is 'real' or not - but this is no safe bet either, so your existing solution should cover you for anything except power users who know what they're doing (who you wouldn't be able to do much against anyway)
I started using FMOD library, because I need to play sounds without gaps in C# application (both one sound in a loop and many sounds in a sequence). Can anyone show me the correct way to do it? I tried make something based on examples, but it's not working as I would like it to work.
Firstly, when I try to set if the sound is looped, while it's playing,
if (value)
sound1.setMode(FMOD.MODE.LOOP_NORMAL);
else
sound1.setMode(FMOD.MODE.LOOP_OFF);
nothing is going on. It only works fine, when I set th mode, before I start playback.
The second issue is: how can I be notified that the sound has reached the end? I tried to do it this way:
channel.setCallback(eofCallback);
where eofCallback is a reference to SoundEndCallback
private FMOD.RESULT SoundEndCallback(IntPtr channelraw, FMOD.CHANNEL_CALLBACKTYPE type, IntPtr commanddata1, IntPtr commanddata2)
{
FMOD.RESULT result;
if (type == FMOD.CHANNEL_CALLBACKTYPE.END)
{
//logic here
}
return FMOD.RESULT.OK;
}
But this callback is reached only when I manually invoke stop() on channel, not when the track ends.
Or eventually do you know any other library that would give me easily what I need? I chose FMOD, because it's quite popular, but I don't like its oldschool C++-like way of coding (no events, no exceptions, etc.).
And I have teh answer for my second question: to get notified you have to firstly set callback as mentioned before, and after that you've got to use System.update() method (it must be called periodically in a loop). This is a kind of polling,
To set the loop mode of a sound at runtime use Channel::setMode, Sound::setMode is like setting the defaults for any channels played from that sound (it won't affect currently playing sounds).
As for Channel::setCallback, make sure you are calling System::update regularly to have the callbacks fire for events like the sound playing to the end.
In C# I use the #warning and #error directives,
#warning This is dirty code...
#error Fix this before everything explodes!
This way, the compiler will let me know that I still have work to do. What technique do you use to mark code so you won't forget about it?
Mark them with // TODO, // HACK or other comment tokens that will show up in the task pane in Visual Studio.
See Using the Task List.
Todo comment as well.
We've also added a special keyword NOCHECKIN, we've added a commit-hook to our source control system (very easy to do with at least cvs or svn) where it scans all files and refuses to check in the file if it finds the text NOCHECKIN anywhere.
This is very useful if you just want to test something out and be certain that it doesn't accidentaly gets checked in (passed the watchful eyes during the diff of everything thats commited to source control).
I use a combination of //TODO: //HACK: and throw new NotImplementedException(); on my methods to denote work that was not done. Also, I add bookmarks in Visual Studio on lines that are incomplete.
//TODO: Person's name - please fix this.
This is in Java, you can then look at tasks in Eclipse which will locate all references to this tag, and can group them by person so that you can assign a TODO to someone else, or only look at your own.
If I've got to drop everything in the middle of a change, then
#error finish this
If it's something I should do later, it goes into my bug tracker (which is used for all tasks).
'To do' comments are great in theory, but not so good in practice, at least in my experience. If you are going to be pulled away for long enough to need them, then they tend to get forgotten.
I favor Jon T's general strategy, but I usually do it by just plain breaking the code temporarily - I often insert a deliberately undefined method reference and let the compiler remind me about what I need to get back to:
PutTheUpdateCodeHere();
An approach that I've really liked is "Hack Bombing", as demonstrated by Oren Eini here.
try
{
//do stuff
return true;
}
catch // no idea how to prevent an exception here at the moment, this make it work for now...
{
if (DateTime.Today > new DateTime(2007, 2, 7))
throw new InvalidOperationException("fix me already!! no catching exceptions like this!");
return false;
}
Add a test in a disabled state. They show up in all the build reports.
If that doesn't work, I file a bug.
In particular, I haven't seen TODO comments ever decrease in quantity in any meaningful way. If I didn't have time to do it when I wrote the comment, I don't know why I'd have time later.
//TODO: Finish this
If you use VS you can setup your own Task Tags under Tools>Options>Environment>Task List
gvim highlights both "// XXX" and "// TODO" in yellow, which amazed me the first time I marked some code that way to remind myself to come back to it.
I'm a C++ programmer, but I imagine my technique could be easily implemented in C# or any other language for that matter:
I have a ToDo(msg) macro that expands into constructing a static object at local scope whose constructor outputs a log message. That way, the first time I execute unfinished code, I get a reminder in my log output that tells me that I can defer the task no longer.
It looks like this:
class ToDo_helper
{
public:
ToDo_helper(const std::string& msg, const char* file, int line)
{
std::string header(79, '*');
Log(LOG_WARNING) << header << '\n'
<< " TO DO:\n"
<< " Task: " << msg << '\n'
<< " File: " << file << '\n'
<< " Line: " << line << '\n'
<< header;
}
};
#define TODO_HELPER_2(X, file, line) \
static Error::ToDo_helper tdh##line(X, file, line)
#define TODO_HELPER_1(X, file, line) TODO_HELPER_2(X, file, line)
#define ToDo(X) TODO_HELPER_1(X, __FILE__, __LINE__)
... and you use it like this:
void some_unfinished_business() {
ToDo("Take care of unfinished business");
}
It's not a perfect world, and we don't always have infinite time to refactor or ponder the code.
I sometimes put //REVIEW in the code if it's something I want to come back to later. i.e. code is working, but perhaps not convinced it's the best way.
// REVIEW - RP - Is this the best way to achieve x? Could we use algorithm y?
Same goes for //REFACTOR
// REFACTOR - should pull this method up and remove near-dupe code in XYZ.cs
I use // TODO: or // HACK: as a reminder that something is unfinished with a note explaining why.
I often (read 'rarely') go back and finish those things due to time constraints.
However, when I'm looking over the code I have a record of what was left uncompleted and more importantly WHY.
One more comment I use often at the end of the day or week:
// START HERE CHRIS
^^^^^^^^^^^^^^^^^^^^
Tells me where I left off so I can minimize my bootstrap time on Monday morning.
// TODO: <explanation>
if it's something that I haven't gotten around to implementing, and don't want to forget.
// FIXME: <explanation>
if it's something that I don't think works right, and want to come back later or have other eyes look at it.
Never thought of the #error/#warning options. Those could come in handy too.
I use //FIXME: xxx for broken code, and //CHGME: xxx for code that needs attention but works (perhaps only in a limited context).
Todo Comment.
These are the three different ways I have found helpful to flag something that needs to be addressed.
Place a comment flag next to the code that needs to be looked at. Most compilers can recognize common flags and display them in an organized fashion. Usually your IDE has a watch window specifically designed for these flags. The most common comment flag is: //TODO This how you would use it:
//TODO: Fix this before it is released. This causes an access violation because it is using memory that isn't created yet.
One way to flag something that needs to be addressed before release would be to create a useless variable. Most compilers will warn you if you have a variable that isn't used. Here is how you could use this technique:
int This_Is_An_Access_Violation = 0;
IDE Bookmarks. Most products will come with a way to place a bookmark in your code for future reference. This is a good idea, except that it can only be seen by you. When you share your code most IDE's won't share your bookmarks. You can check the help file system of your IDE to see how to use it's bookmarking features.
I also use TODO: comments. I understand the criticism that they rarely actually get fixed, and that they'd be better off reported as bugs. However, I think that misses a couple points:
I use them most during heavy development, when I'm constantly refactoring and redesigning things. So I'm looking at them all the time. In situations like that, most of them actually do get addressed. Plus it's easy to do a search for TODO: to make sure I didn't miss anything.
It can be very helpful for people reading your code, to know the spots that you think were poorly written or hacked together. If I'm reading unfamiliar code, I tend to look for organizational patterns, naming conventions, consistent logic, etc.. If that consistency had to be violated one or two times for expediency, I'd rather see a note to that effect. That way I don't waste time trying to find logic where there is none.
If it's some long term technical debt, you can comment like:
// TODO: This code loan causes an annual interest rate of 7.5% developer/hour. Upfront fee as stated by the current implementation. This contract is subject of prior authorization from the DCB (Developer's Code Bank), and tariff may change without warning.
... err. I guess a TODO will do it, as long as you don't simply ignore them.
This is my list of temporary comment tags I use:
//+TODO Usual meaning.
//+H Where I was working last time.
//+T Temporary/test code.
//+B Bug.
//+P Performance issue.
To indicate different priorities, e.g.: //+B vs //+B+++
Advantages:
Easy to search-in/remove-from the code (look for //+).
Easy to filter on a priority basis, e.g.: search for //+B to find all bugs, search for //+B+++ to only get high priority ones.
Can be used with C++, C#, Java, ...
Why the //+ notation? Because the + symbol looks like a little t, for temporary.
Note: this is not a Standard recommendation, just a personal one.
As most programmers seem to do here, I use TODO comments. Additionally, I use Eclipse's task interface Mylyn. When a task is active, Mylyn remembers all resources I have opened. This way I can track
where in a file I have to do something (and what),
in which files I have to do it, and
to what task they are related.
Besides keying off the "TODO:" comment, many IDE's also key off the "TASK:" comment. Some IDE's even let you configure your own special identifier.
It is probably not a good idea to sprinkle your code base with uninformative TODOs, especially if you have multiple contributors over time. This can be quite confusing to the newcomers. However, what seems to me to work well in practice is to state the author and when the TODO was written, with a header (50 characters max) and a longer body.
Whatever you pack into the TODO comments, I'd recommend to be systematic in how you track them. For example, there is a service that examines the TODO comments in your repository based on git blame (http://www.tickgit.com).
I developed my own command-line tool to enforce the consistent style of the TODO comments using ideas from the answers here (https://github.com/mristin/opinionated-csharp-todos). It was fairly easy to integrate it into the continuous integration so that the task list is re-generated on every push to the master.
It also makes sense to have the task list separate from your IDE for situations when you discuss the TODOs in a meeting with other people, when you want to share it by email etc.