In a previous post about locking in Rock, Paper, Azure, I said this somewhat offhand:
In this case, there’s no reason to use such code in a bot. The only time you’d need to is if your bot has a static method/object reference, but that’s a bad idea in a bot because it will lead to unpredictable results. Your bot should have only instance members.
I should’ve called that out more, and in this case, we have a player who lost because of it. It’s especially tough because things seemingly worked fine, until the final tournament round. Here’s why, and here’s some information on static variables (shared in VB) for those who haven’t used them before.
In short, a static modifier on a method or variable makes the member part of the type instead of the class. This is really useful on helper methods in particular, because a static member can be used without instantiating the type to which the member belongs.
Static objects (variables) – in any code – should be a red flag. They have very specific advantages and lower overhead (only 1 is created no matter how many objects of that type are created) – BUT, they can burn you easily if you’re not certain how the object is loaded and used. (Static methods, as a general rule, tend to have less risk than static objects/variables.) Unfortunately, that’s what happened in last Friday’s competition to one of our players.
So how can they burn you? For one, they’re not thread safe. Of course, they _could_ be thread safe, but you’d have to be cognizant of what they are doing to make them thread safe. (Non-statics might not be thread safe either, however, using statics implies global reuse so it heightens the exposure of thread safety issues and can be hard to track down.) One example: we modified the original engine to do multithreading and the original log had a static method that used a StringBuilder to build a log file. This caused problems because the StringBuilder is not thread safe – so we had to add locking. The problem was always there (even if it wasn’t static), but the problem never manifested because the core was single threaded. Another way they can burn you is that two or more objects may be accessing the objects in an nondeterministic way, leading to unpredictable results.
The unfortunate part about this in particular was that the issue didn’t manifest until the main tournament round – so everything appeared fine until the final round. The game engine runs two types of rounds: player rounds, and full rounds. In either case, the engine will spin up many threads to execute the games – but during a player round, the engine loops the new bot against everyone else. As other players submit their bots, the engine will load your bot only once. Because your bot is loaded only once, there’s really no chance of static variables causing a problem, much like the StringBuilder example above.
But during the tournament round, all of a sudden many more games are played. Consider that with 50 players, only 49 games are played when a new bot is uploaded. But in a full round, 1,225 games are played! There is a much stronger chance your bot will have multiple instances loaded concurrently, and modifying static variables will cause the bots to go haywire.
So, the lesson of the week is: don’t use statics in a bot! Question or comment about a bot? Let us know…
In a Windows Azure project, you can specify the Guest OS version for your VM. This is done by setting the osVersion property inside the ServiceConfiguration file: If you don’t specify a version explicitly, the latest Guest OS is chosen for you. For production applications, it’s probably best to always provide an explicit value, and I have a real world lesson that demonstrates this! MSDN currently has a Guest OS Version and SDK Compatibility Matrix page that is extremely helpful if you’re trying to figure out which versions offer what features. I recently ran into a problem when examining some of my performance counters – they were all zero (and shouldn’t have been)! Curious to find out why, I did some digging (which means someone internal told me what I was doing wrong). In short, I had specified a performance counter to monitor like so: "\ASP.NET Applications(__Total__)\Requests/Sec". This had worked fine, but when I next redeployed some weeks later, the new Guest OS (with .NET Fx 4.0) took this to mean 4.0 Requests/Sec, because I didn’t specify a version. So, I was getting zero requests/sec because my app was running on the earlier runtime. This was fixed by changing the performance counter to "\ASP.NET Apps v2.0.50727(__Total__)\Requests/Sec". For more information on this, check out this article on MSDN. And thanks to the guys in the forum for getting me up and running so quickly!
Ever get a dialog box like this when opening a project? This can occur under a number of scenarios – for example, opening a solution on a network share. But in this case, the files themselves were tagged while being downloaded (as you can see in the path – it’s on my desktop). If you right click the solution file (or other file in the group), you’ll see the file is tagged as such: The problem is, all files in the group have to be unblocked, and if you’ve got a large project, it can be somewhat of a pain to do that. There are two solutions, then. If you have the original Zip/Rar/whatever archive file, you can unblock that file, and then when the rest are abstracted, you’re good to go. Second, if you can’t do that, you need to remove the block on all of the files in the solution. Sysinternals/Microsoft has a tool to do just that: streams. Streams is a command line tool – you specify a directory and it can remove the streams for you (-d switch). The –r switch will allow it to recurse subdirectories: Next time the project is opened – presto! No warning. Head over to the sysinternals site here.
Part 4 of the 5-part series is up on Channel 9. In the previous screencasts, we looked at setting breakpoints and how to work with advanced breakpoints, filters, and working with multiple threads. We also took a quick look at tracepoints. In part 4, we'll look at the watch windows, the immediate window, and Make Object ID command…
The third in the series of debugging tips has been posted to Channel 9(including the player here, too). A quick abstract: In parts 1 and 2, we looked at setting breakpoints, and talked about setting up advanced breakpoints using hit counts and some simple conditions. In part 3, we’ll dive a little deeper into some conditions by writing methods to help debug our application, then look at using the filter breakpoint modifier to debug multithreaded applications. Finally, we’ll take a quick look at tracepoints.
Part 1 was a pretty basic introduction to setting breakpoints. Now it’s time to have a bit more fun! In part 2, I’ll look at using breakpoint modifiers – specifically, using the hit count modifier, and then the condition modifier. The condition modifier can be incredibly powerful – while we can corrupt the state of our application pretty easily (as I’ll demonstrate), it starts to open a whole new world for debugging more efficiently.
Recently, I’ve been doing a number of talks on tips and tricks with the Visual Studio debugger. I thought it would be a good idea to start putting together a series of DevNuggets on these tips – so here is the first! Part 1 is primarily an introduction into setting breakpoints … turns out there are number of ways to set breakpoints other than just clicking in the gutter. This is primarily of interest to entry level developers, but the follow parts will get into some advanced techniques.