Monday, September 17, 2007

My SQL Server 2005 is Slow

Testing code that queries SQL Server 2005, I kept observing long delays. Sometimes my tests would execute in less than one second, which was expected. Frequently, they would take 30 to 120 seconds!

A little digging into the SQL Server, I found the two top waits were SQLTRACE_BUFFER_FLUSH and RESOURCE_SEMAPHORE, both of which would grow in correlation to delays I observed when running my unit tests.

A little reading found: this forum topic and this kb article. The former being the most useful. It turns out SQL 2005 will run a trace by default; to assist in fixing problems later. (read "default trace enabled" in SQL Books Online) Unfortunately on my development box, it appears the trace is the source of my delays. So my solution is to turn off the default trace using:

exec sp_configure 'show advanced options',1
reconfigure
exec sp_configure 'default trace enabled',0
reconfigure


After this, my tests always ran in less than one second!

Wednesday, August 01, 2007

IronRuby alpha

John Lam has posted a nice article about the current work on IronRuby. My development team has already started using Ruby to write unit tests. We are currently using CRuby but plan to port to IronRuby once it is released. Our product is written on .Net so IronRuby will fit our project very well.

Diff tools

SourceGear just released an update to their free DiffMerge program. This product caught my eye because it has a 3-way merge. My current favorit Diff tool is Beyond Compare 2 from Scooter Software ($30). It has more features than DiffMerge, but doesn't include the 3-way merge which I sometimes need. The best merge tool I've ever used is Araxis Merge, but it costs $269 for the pro edition, I can't justify the extra cost vs the $30 Beyond Compare 2. Araxis Merge's price tag was worth it when I was working with an offshore team. I had to 3-way merge code from the US and India across many files and directories. It would have been too expensive in time if I didn't use Araxis Merge for that task.

Thursday, July 05, 2007

IIS Authentication and Access Diagnostics Tool

I just got through configuring SQL Server 2005 for a Scale-Out Deployment. One problem I ran into was the NTML "Dual Hop" issue. Fortunately I found the IIS Authentication and Access Diagnostics Tool which helped quickly identify the issue. This tool hasn't been mentioned much, so I am recommending it.

Now I've got a happy system with Report Server running separately from Reporting Services Database. Everything is working great: Reports and Report Builder. I've seen other sites which said this configuration would not work. I managed to get it working using Integrated Authentication and Kerberos.

Enjoy!

Monday, May 21, 2007

Ruby Require Idiom

Ruby's "require" command can accidentally load the same file twice.

The following example shows this problem (2 files)...

#----------
# file: problem.rb
puts "#{__FILE__} loaded"

#----------
# file: run_me.rb
require '././problem' #=> .\problem.rb loaded
require 'problem' #=> ./problem.rb loaded



When run_me requires problem.rb using slightly different paths, Kernel#require loads it twice. This happens because Kernel#require tracks the files it has loaded in the $" array. It only does a String compare, so if the file names differ it doesn't find the match.

There are several ways to avoid loading the same file twice. The first technique is to call require using the absolute path of the file. Since every file only has one absolute path, Kernal#require will not get confused. To get the absolute path, we can use File.expand_path as shown in the following example.
#----------
# file: ok.rb
puts "#{__FILE__} loaded"

#----------
# file: run_me.rb
require File.expand_path('././ok') #=> C:/ruby/require/expand_path/ok.rb loaded
require File.expand_path('ok') #=>



Another effective technique is using indirection. That is, require a file that requires other files. This technique works really well for loading libraries and gems. The first file may get loaded multiple times because of arguments to Kernel#require. But once inside this file, all calls to Kernel#require are the same. So the sub-files are not loaded multiple times. The following example illustrates this solution.

#----------
# file: run_me.rb
require 'base' #=> ./required_by_base.rb loaded
require '././base'

#----------
# file: base.rb
$:.unshift(File.expand_path(File.dirname(__FILE__))) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

require 'required_by_base'

#----------
# file: required_by_base.rb
puts "#{__FILE__} loaded"



See how "base.rb" is required twice using different file paths. Kernel#require actually loaded "base.rb" twice. But "base.rb" didn't do anything except call Kernel#require to load other files. Since the parameter 'required_by_base' was the same in both calls, "required_by_base.rb" was only loaded once.

The first two lines of "base.rb" add the current directory to the search path. This wasn't really necessary for this example since the "required_by_base.rb" file is in the same directory. However, if the require used a relative path to another directory, it would have failed. By adding the current directory to the front of the search path this ensures the correct files are loaded.

If you look closely, you will see that the File.expand_path is used to put the absolute path into the search path. This avoids adding the same path twice.