Instance Selection Algorithm: spymemcached vs. memcached-session-manager

I recently evaluated whether to use memcached-session-manager [1] for one of our webapps. Although memcached-session-manager bases on spymemcached [2] for communicating with memcached, I was surprised that it uses a significant different algorithm for selecting a memcached instance (out of a pool of given memcached instances) than the native implementation of spymemcached.

Spymemcached

Spymemcached selects the instance by calculating a hash of the element’s key and using that hash to determine the instance. Simplified this could be done by compute:

server = serverlist[hash(key)%serverlist.length]

To distribute the elements uniformly on all nodes often Consistent Hashing [3], e.g. KETAMA, is used as hash function. See [4] for details.

Memcached-Session-Manager

In contrast to that, memcached-session-manager doesn’t use hashing at all – it simply “selects the memcached node randomly” [5] (excluding failover nodes). After that the node id is encoded in the session id like 72d9ffcb00d836b3248d8bd95ce2e641-n1.tomcat1 (“n1”). All further accesses are selected by this value.

How to not convert a Boolean to boolean

On my last code review session I stumbled over that lovely piece of code:

Boolean wrapper = foo();
boolean primitive = Boolean.parseBoolean(""+wrapper);

A somehow interesting way of converting a Boolean to it’s primitive.

I guess this was done to avoid a NullPointerException in case wrapper is null. But it violates one simple rule: write readable code.

Of course, this line isn’t hard to understand—but do you know for sure the outcome of the parseBoolean-method when the argument is null or an empty String? Is it ‘false’, ‘true’ or will the method throw an exception? To make it even worse: “”+wrapper will return the String “null” (yep – a String of length 4) when wrapper is null. Can parseBoolean handle this too?

So how to (really) avoid a NullPointer here? Simply use:

Boolean wrapper = foo();
boolean primitive = wrapper == null ? false : wrapper.booleanValue();

or (cooler but a little less readable):

Boolean wrapper = foo();
boolean primitive = wrapper != null && wrapper.booleanValue();

UninstallWMISchemaExecute (0x8004401e) when updating VisualSVN on Windows XP

The problem

On the attempt to update VisualSVN on my Windows XP I struggled with the following exception quite a long time:

Custom action UninstallWMISchemaExecute failed: Diese Datei ist keine gültige MOF-Datei. (0x8004401e)
Screenshot of UninstallWMISchemaExecute-Exception (0x8004401e) when updating VisualSVN on Windows XP

UninstallWMISchemaExecute when updating VisualSVN

I was never faced with WMI before so I started from scratch and choosed to try’n’error. A great help was the artikel found in [1] and after a while I succeeded—but: I still have no clue why my solution worked, nor could I assure that it is side-effect-free. So use on your own risk!

The solution

  1. Disable the WMI service
    sc config winmgmt start= disabled 
    (make sure there is a blank between 'start' and 'disabled')
  2. Stop the WMI service
    net stop winmgmt
  3. Go to %windir%/System32/wbem and rename the repository-folder
    cd C:\WINDOWS\System32\wbem
    rename Repository Repository-old
  4. Find the *.mof-file in %windir%/System32/wbem which belongs to VisualSVN
    In my case the file was named “6E9A2709F6EB23A5E2F059ACD767AD78.mof”. Inside there were multiple occurences of the string “VisualSVN”—which I found by using Notepad++’s search-in-files-funktionality [2]. Note that the Windows search won’t lead to any useable results since Windows doesn’t do a text-search on *.mof-files by default.
  5. Remove the file found in step 4
  6. Search the registry on occurences of “VisualSVN” and remove every found item
    I guess especially the key “Autorecover MOFs” in

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM

    was an entry which recreated the faulty *.mof all over again.

  7. Enabled the WMI service
    sc config winmgmt start= auto
  8. Start the VisualSVN-Installation

Reference

  1. [1] http://blog.technical-life.at/2011/09/nice-to-know-wmi-steuerung-reparieren
  2. [2] http://npp-community.tuxfamily.org/documentation/notepad-user-manual/searching/searching-files

A quick refactoring using TestNG’s expectedExceptions

I recently crossed a TestNG-test which looked like this:

@Test
public void noResultsTest() {
	// test
	String query = " ";
	Exception exception = null;
	List foos = null;
	try {
		foos = barService.search(query);
	} catch (SystemError e) {
		// input was wrong
		exception = e;
	}

	// assert
	Assert.assertNotNull(exception, "There was an exception");
	Assert.assertNull(foos);
}

Obviously this test should check that barService#search throws an Exception in case the input is a blank.

But there are a few things to mention:

  • TestNG is capable of checking if an expected exception was thrown in a test. Simply use @Test(expectedExceptions={..}).
  • The check that Assert.assertNull(foos) holds true is useless. Either no exception was thrown and Assert.assertNotNull(exception, "There was an exception") will fail or an exception was thrown and foos will not be assigned with any value.

So the test could be rewritten like this:

@Test(expectedExceptions={ SystemError.class })
public void keineBerufeTest2() throws SystemError {
	foos = barService.search(" ");
}