Unintelligible

Tuesday, October 20, 2009

Named Reader Writer Lock in C#

A while ago, I found an article about implementing a named lock class in C#, allowing for the following code:

private static NamedLock<string> namedLock = new NamedLock</string><string>();
public void DoSomethingConcurrent(string lockName)
{
    using (namedLock.Lock(lockName))
    {
       //Do something concurrent
    }
}
</string>

This is useful because it allows the same code block to be run concurrently, with locking occurring depending on the arguments being passed in. The author thought it might be useful to have some reader-writer type functionality added in too though; since I had a similar requirement, I wrote a named reader-writer lock, based partly on the NamedLock posted above but using a ReaderWriterLockSlim as the underlying lock rather than a simple Monitor.

I’ve posted the code to Github, including a unit test suite. The most interesting file is the class itself. Usage is almost identical to the NamedLock:

private static NamedReaderWriterLock<string> namedRWLock = new NamedReaderWriterLock</string><string>();
public void DoSomethingConcurrent(string lockName)
{
    using (namedRWLock.LockRead(lockName))
    {
       //Do something concurrent that only requires 
       //read access to the resource
    }
    using (namedRWLock.LockUpgradeableRead(lockName))
    {
       //Do something concurrent that only requires 
       //read access to the resource, but that may require
       //upgrading to a Write lock later in the code
    }
    using (namedRWLock.LockWrite(lockName))
    {
       //Do something concurrent that requires 
       //write access to the resource
    }
}
</string>

Performance-wise, the reader-writer functionality does seem to improve concurrent access over the named lock; here’s the output of the performance tests running on my machine:

NameLock_vs_NamedReaderWriterLockSlim_PerformanceTest_Balanced
 
Run 1 - finished NamedRWLock run in 3734.2794ms
Run 1 - finished NamedLock run in 5499.8592ms
Run 1 - finished Monitor run in 5468.61ms
Run 2 - finished NamedRWLock run in 3609.2826ms
Run 2 - finished NamedLock run in 5468.61ms
Run 2 - finished Monitor run in 5468.61ms
Run 3 - finished NamedRWLock run in 3609.2826ms
Run 3 - finished NamedLock run in 5468.61ms
Run 3 - finished Monitor run in 5515.4838ms
 
3 passed, 0 failed, 0 skipped, took 47.92 seconds.
 
NameLock_vs_NamedReaderWriterLockSlim_PerformanceTest_SkewedRead
 
Run 1 - finished NamedRWLock run in 6656.0796ms
Run 1 - finished NamedLock run in 8843.5236ms
Run 1 - finished Monitor run in 8812.2744ms
Run 2 - finished NamedRWLock run in 6562.332ms
Run 2 - finished NamedLock run in 8812.2744ms
Run 2 - finished Monitor run in 8812.2744ms
Run 3 - finished NamedRWLock run in 6562.332ms
Run 3 - finished NamedLock run in 8812.2744ms
Run 3 - finished Monitor run in 8812.2744ms
 
3 passed, 0 failed, 0 skipped, took 76.59 seconds.

These tests compare the performance of the NamedReaderWriterLock with the NamedLock, using a standard Monitor as a control value. The first set of tests balances reads and writes, whereas the second performs four times more reads than writes (and likely reflects real-life scenarios more closely.)

The NamedReaderWriterLock provided around 35% improvement over the NamedLock in the test where as many writes as reads are performed, and a 25% improvement in the test skewed towards reads. This is a reasonably figure, although in the greater scheme of things it’s likely to be a only a minor improvement compared to the cost of, say, making a DB call; still, it’s worth having.

The code is available under the BSD license.

posted by Nick at 10:17 pm - filed in .net  

Tuesday, July 28, 2009

Installing Selenium-RC as a Windows service

Installing Windows as a service is reasonably straightforward - based on the instructions for Fitnesse, which unfortunately seem to have been deleted from the Fitnesse wiki, but which have been reproduced here.

There are two parts to doing this - the first, registering the service using srvany.exe (which wraps any executable as a service), and the second, adding the keys to the registry to tell srvany.exe how to launch Selenium-RC. srvany.exe is a part of the Windows Resource Kit, if you don’t have it already you will need to download it from Microsoft.

The following will register the Selenium service - on the command line (all in one line):

"C:\Program Files\Windows Resource Kits\Tools\instsrv.exe" SeleniumRC
"C:\Program Files\Windows Resource Kits\Tools\srvany.exe" -a [myuser] -p [mypass]

This is assuming the Windows Resource Kit has been installed to its default location, “C:\Program Files\Windows Resource Kits”. Also, note that the user supplied needs to have the Log On As Service permissions assigned.

Now, add the following keys to the registry - this text can simply be copied-and-pasted to a .reg file, then double-clicked to add the entries to the registry:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SeleniumRC\Parameters]
"Application"="java.exe"
"AppDirectory"="C:\\Program Files\\selenium-server-1.0.1"
"AppParameters"="-Xrs -jar selenium-server.jar"

You should now be able to start the service - if you get an error about the service failing to start due to a logon issue, make sure that the user you are using to run the service has been granted Log On As A Service permission (editing the service logon credentials in the Services MMC snap-in and saving the changes will cause this to happen automatically.)

posted by Nick at 10:08 pm - filed in testing, windows  

Sunday, March 8, 2009

Rubyists and Photographers, slight return

A few months ago, I posted an entry on how Rubyists sometimes get distracted by the power of the language, preferring lengthy debates on programming aesthetics to actually writing (efficient) code. I compared this to photography, in which aspiring photographers sometimes get lost in technical discussions rather than focussing on the work they produce. Then I came across this quote, which concisely expresses in 3 sentences what I hadn’t managed in an entire post:

Every medium suffers from its own particular handicap. Photography’s greatest handicap is the ease with which the medium as such can be learned. As a result, too many budding neophytes learn to speak the language too long before they have anything to say.

(Will Connell, 1949, via Brendan MacRae, via Tim Bray)

The point of my original post was that the same may apply to Ruby; the language’s power and accessibility makes everything seem so easy, that it becomes tempting to engage in discussions about the finer points of programming aesthetics rather than focussing what one has to say (i.e. the problems one chooses to solve.)

posted by Nick at 1:15 pm - filed in ruby  

Sunday, March 8, 2009

Adding a Windows service using sc

The ‘sc‘ utility can be used to create, delete or edit a Windows service. It can be used for any executables (as opposed to installutil, which can only be used for .Net services). Its help is available using sc /help (and is also available on MSDN); however, I found the output slightly confusing, so for my own reference here’s an example for creating a service for the Subversion server:

sc create svnserve binPath= "\"C:\Program Files\CollabNet Subversion Server\svnserve.exe\" 
  --service -r \"c:\svn_repository\" --listen-port \"3690\"" DisplayName= "Subversion Server"

This passes two parameters, the binPath and the DisplayName (the rest are the directives Subversion expects when running as a service). The trick here is the space between the ‘=’ sign after the parameter name and the parameter value; the service won’t be installed otherwise.

posted by Nick at 12:53 pm - filed in windows  

Monday, February 2, 2009

Mona Lisa image evolution in Ruby (JRuby)

Like several other people, I was fascinated by Roger Alsing’s post shortly before Christmas describing his program to evolve an image look like Leonardo’s Mona Lisa, using only semi-transparent polygons. This uses genetic programming (or perhaps more accurately, simulated annealing, a Monte Carlo method) to evolve an image, comparing each evolved image to its parent and deciding whether it is closer to the target image; if it is closer to the target, the image is retained and then evolved further.

Since Roger released his source code, there have been several other implementations in different languages, such as Javascript and Clojure. I thought that converting the program to another language would be an excellent way to understand how it works; so, I converted it to Ruby (actually JRuby, as Swing is used for drawing the images and the user interface).

I’ve uploaded the code to GitHub; my implementation is pretty much a straight port of Roger Alsing’s original code though, and generally speaking it’s a little quick and dirty; I may eventually spend a little time tidying and/or optimising it, but as of yet it isn’t either elegant or fast.

This short clip shows the evolution of the selected candidates over 75000 generations (around four hours on my machine).

posted by Nick at 8:50 pm - filed in java, ruby  

Saturday, January 10, 2009

Touch typing update - one year after

It’s been a year now since I switched to the Dvorak keyboard layout and learned to touch-type, so it seemed like a good time to assess progress so far.

I now consistently type between 60 and 70 WPM, depending on the day and the text I need to type. I’m reasonably happy with this, but when I originally switched, I was hoping that I would get up to 80-90WPM within a year. Also, I can’t really touch-type numbers, and I usually need to look at the keyboard to type some of the non alpha-numerical numbers that get used often when developing (e.g. ‘[', ']‘, ‘$’, ‘^’ etc.). Finally, typing still hasn’t really become as automatic as I’d hoped it would; to achieve high speeds, I still need to concentrate on typing, whereas I was hoping that I would have interned the typing to an extent that I didn’t really need to think about it anymore.

So, I think I’m going to start practicing again (in fact, I already started a little over Xmas). I’m kind of hoping to have resolved all of the above by June this year, so that I can finally stop thinking about typing :-)

posted by Nick at 3:20 pm - filed in dvorak  

Monday, December 1, 2008

Event Log access permissions for ASP.NET application pools

When running an application pool in IIS under a different user than the default, for an application that requires write access to the Event Log (for example, when trying to create a new event source in your application), it is necessary to grant that user sufficient access to the event log in the registry. Otherwise, you would receive the following error:

System.Security.SecurityException: Requested registry access is not allowed.

However, using Windows 2003 Server, I found that granting ‘read’ access to the event log wasn’t enough; the full set of permissions I ended up need to grant to the app pool user on the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog key in the registry is as follows:

Permissions for event log access in IIS

I hope that this helps someone.

posted by Nick at 7:43 pm - filed in windows  

Wednesday, July 30, 2008

Migrating a Subversion repository to a remote Git repository

Migrating an existing SVN repository to git is pretty easy; here’s a quick step-by-step guide (and reminder to myself).

Before we start, let’s make sure git and git-svn are installed:

$ sudo apt-get install git git-core git-svn

1. Getting the code out of Subversion

First, use git-svn to get a copy of the remote Subversion repository you want to migrate. For instance:

$ mkdir MyProjectSVN && cd MyProjectSVN
$ git init
$ git-svn clone --authors-file=git-svn-users.txt --stdlayout https://my.svn.repository.com/MyProject

A couple of words on these options:

  • clone gets a copy of the entire repository, including all commit history, tags and branches
  • –stdlayout tells git-svn that you have laid your SVN repository as per the SVN recommendations, namely with top-level folders for trunk, tags and branches. If not, you can specify the paths for these relative to the repository root using the –trunk, –tags and –branches switches respectively (instead of –stdlayout)
  • the –authors-file option allows you to map SVN users to git users, for the commit history; the file should be in this format:
    svnUserId = First Last

This process will take a little while, especially for large repositories. When that’s done, git-svn will have created a new MyProject folder containing the full repository.

We can verify its contents:

$ cd MyProjectSVN
$ ls -la
$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[svn-remote "svn"]
    url = https://my.svn.repository.com/MyProject
    fetch = trunk:refs/remotes/trunk
    branches = branches/*:refs/remotes/*
    tags = tags/*:refs/remotes/tags/*

Note that the location of our remote SVN repository is stored in the .git/config - this allows git-svn to commit any changes you make back to the main SVN repository if you want to (how to do this is well explained in the introduction to git-svn for Subversion deserters).

2. Creating a remote git repository

However, our aim is to replace our existing remote SVN repository with a remote git repository; to do so, we first need to create an empty git repository on the remote machine, which we will then upload the repository we just created locally. This assumes that git-core is installed on the remote machine:

$ ssh me@remote-machine.com
$me@remote&gt;: mkdir git/MyProject.git
$me@remote&gt;: cd git/MyProject.git
$me@remote&gt;: git --bare init
$me@remote&gt;: pwd
/home/me/git/MyProject.git
$me@remote&gt;: exit

A few notes on this:

  • the –bare option passed into git init tells git that we just want the repository, not the files (it isn’t necessary to have git create and update the code files remotely; we just want it to manage the repository. The code files and the repository are held in two different places in git.)
  • Note the output of pwd - this will be the path we will use to access the remote repository from our local box.

3. Clone the local repository

Now that we have created the remote repository, we can upload our local repository to its remote location. First though, back on our local machine, we’ll clone the git repository we used to extract the data from SVN:

$ cd ..
$ mkdir MyProject && cd MyProject
$ git init MyProject
$ cd ..
$ git clone MyProjectSVN MyProject
$ rm -rf MyProjectSVN

This will ensure we have a clean repository without any leftover SVN information. Now, we need to tell git where the remote repository is located:

$ cd MyProject
$ git remote add origin ssh://me@remote-machine.com/home/me/git/MyProject.git

Here:

  • remote add: adds a remote location
  • origin: the name of the remote location

Next, we need to tell git who we are:

$ git config --add user.name "First Last"
$ git config --add user.email me@domain.com

Let’s have a quick look at our configuration:

$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[user]
    name = First Last
    email = me@domain.com
[remote "origin"]
    url = ssh://me@remote-machine.com/home/me/git/MyProject.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Note the user information and the remote location have been added to the config file.

4. Uploading to the remote git repository

That should be it - we’re ready to upload the local repository to the remote location. It’s as simple as:

$ git push --all origin
  • git push –all origin : push the all the local branches and tags to the remote repository, creating new remote branches of the same name

This will upload the contents of the master branch to the origin remote repository. Let’s check that we also have any tags and branches from subversion:

$git branches -r
branch1
branch2
tags/tag1
tags/tag2
  • git branches -r: list all remote branches

5. Accessing our new remote git repository

The contents of our local git repository were retrieved from SVN; now that we’ve uploaded that to our new remote git repository, we can get rid of the intermediary local repository we were working on, and begin using with our remote git repository in earnest:

$ cd ..
$ rm -rf MyProject
$ mkdir MyProject && cd MyProject
$ git init
$ git config --add user.name "First Last"
$ git config --add user.email me@domain.com
$ git remote add origin ssh://me@remote-machine.com/home/me/git/MyProject.git
$ git pull origin master
$ git branch -a
* master
  origin/master
  origin/branch1
  origin/branch2
$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[user]
    name = First Last
    email = me@domain.com
[remote "origin"]
    url = ssh://me@remote-machine.com/home/me/git/MyProject.git
    fetch = +refs/heads/*:refs/remotes/origin/*

That’s it! We’ve just pulled the master branch from our remote git repository, and at this stage, we are ready to start working with git locally. Note that when we ask git to tell us about all of the branches it knows about, it mentions all of the branches and tags from SVN as remote, but not local; this is because we only pulled the master branch from the remote repository.

We can now edit files, commit changes, and then push those changes to our remote repository; a good place for SVN users to start learning how to do this is the Git-SVN Crash Course

Note: if you have git-svn installed on the remote machine and the SVN repository is accessible from your remote machine, you can use git-svn to clone the repository from SVN directly on the remote machine using the –bare option (which gets just the repository, without the files). You can then use git pull to get a local copy once the remote information has been set up; this involves less steps, and would likely be a little quicker. I didn’t have access to git-svn remotely or the permissions to install it (shared hosting), so this wasn’t an option for me.

The following guides were helpful to me:
Setting up a new remote git repository - Toolman Tim

An introduction to git-svn for Subversion deserters
Converting a Subversion repository to git - Ruby Forums
Converting Subversion repositories to Git - Redline Software

posted by Nick at 9:02 pm - filed in linux  

Sunday, July 27, 2008

WSE 2.0 in Visual Studio 2008

A slightly older .Net 2 application I wrote for a client to upload files to Amazon S3 makes use of the Amazon S3 SOAP API. The SOAP API has the advantage over the REST API of being able to stream large files as DIME attachements when uploading to the S3 servers, rather than trying to load them up in one go, which is handy when uploading large files. The S3 WS API requires Microsoft’s Web Services Enhancements (WSE) 2.0 though, rather than the later WSE 3.0, because in WSE 3.0 DIME is replaced by MTOM (which Amazon doesn’t support - in typical WS-* way).

However, when I tried to install this, I got the following error:

Unknown error in CorBindToRuntimeHost

Error 1001.InstallUtilLib.dll: Unknown error in CorBindToRuntimeHost

The workaround (a reminder to myself) is to use the WSE 2.0 SP3 installer rather than the older versions that come up when searching for WSE 2.0 on google.

posted by Nick at 6:24 pm - filed in .net, windows  

Saturday, March 15, 2008

Dvorak keyboard in Ubuntu/Xubuntu

For my own reference, a couple of ways of setting up the Dvorak keyboard in Ubuntu Linux.

In Gnome:

System > Preferences > Keyboard > Layouts tab > Add button > Dvorak

For a single terminal session:

loadkeys dvorak

Adding this line to your .bashrc should result in it applying to all your terminal sessions.

All X sessions (including the GDM logon screen and Gnome):

For all X sessions (including the GDM logon screen and Gnome), add Option "XbdLayout" "dvorak" to /etc/X11/xorg.conf as such:

Section "InputDevice"
  Identifier "Generic Keyboard"
  Driver "kbd"
  Option "CoreKeyboard"
  Option "XkbRules" "xorg"
  Option "XkbModel" "pc105"
  Option "XkbLayout" "dvorak,gb" #use the dvorak keyboard layout
EndSection

This allows switching between the Dvorak and GB layouts by pressing both shift keys at once.

System-wide:

Simply make sure that /etc/default/console-setup contains the following lines (replacing any options with the same names that might already exist):

XKBLAYOUT="us"
XKBVARIANT="dvorak"

The change will take place after the next reboot. This is equivalent to choosing Dvorak as the default keyboard layout during installation, or running sudo dpkg-reconfigure console-setup from the command line.

posted by Nick at 2:20 am - filed in dvorak, linux  
Next Page »