Questions that stumps me
Answering customer questions
Multi Threading Insanity
![]()
Insanity: doing the same thing over and over again and expecting different results.
Albert Einstein
You obviously never done any multi threading work, dude!
The seven deadly sins for the developer (* some restrictions apply)
Originally posted at 3/30/2011
I have seen all of those in production code…
-
throw new NullReferenceException();
-
public class AbstractController : Controller // or // public class AbstractPag : Page { public static bool IsAdmin { get;set; } }
-
public static class BlogMgr { public static void AddPostToBlog(Blog blog, Post post) { blog.Posts.Add(post); post.Blog = blog; } }
* I could only think of three, but I didn’t want to modify the title. Can you complete the list?
Code review ranking methods
It really happened, legacy programmers tales
Fairy tales always start with “Once upon a time”, and programmers tales starts with “when I was at a client”…
Two days ago I was a client, and the discussion turned to bad code bases, as it often does. One story that I had hard time understanding was the Super If.
Basically, it looked like this:
I had a hard time accepting that someone could write an if condition that long. I kept assuming that they meant that the if statements were 50 lines long, but that wasn’t the case.
And then yesterday I had an even more horrifying story. A WCF service making a call to the database always timed out on the first request, but worked afterward. What would be your first suspicion? Mine was that it took time to establish the database connection, and that after the first call the connection resided in the connection pool.
They laughed at my naivety, for it wasn’t connecting to the database that caused the timeout, it was JITting the method that the WCF service ended up calling.
Yep, you got that right, JITting a single method (because the runtime only JIT a single method at a time). I had even harder time believing that, until they explained to me how that method was built:
Some interesting stats:
- It had a Cyclomatic Complexity of either 4,000 or 8,000, the client couldn’t remember.
- The entire Rhino Mocks codebase fits in 13,000 LOC, so this single method could contain it several times over.
But you know what the really scary part is?
I upgraded from Super If to Black Hole Methods, and I am afraid to see what happen today, because if I get something that top the Black Hole Method, I may have to hand back my keyboard and go raise olives.
What Amazon considers Fantasy
My Erlang Religious Moment
NHibernate – Get Thou Out Of My Database – 2nd Edition
Following up on my previous post, the customer has complained about table names like [tbl_-1434067361], apparently they felt that this was misusing their naming policy. I told them that while I understood that, it did meet their naming policy. I got a new naming policy that stated that numbers are not allowed in column or table name, (and showing forethought) that table names must be composed of valid English words.
I, of course, decided that if this is what they wanted, they will get just that. And created this:
The words.txt file was taken from this URL: http://www.puzzlers.org/pub/wordlists/pocket.txt
The result is exactly per their specification:
create table [tbl_colonel] ( [col_verbiage] INT IDENTITY NOT NULL, [col_unsparing] NVARCHAR(255) null, [col_indomitable] NVARCHAR(255) null, [col_bulldog] BIT null, [col_thank] DATETIME null, primary key ([col_verbiage]) ) create table [tbl_stump] ( [col_upheaval] INT IDENTITY NOT NULL, [col_promissory] NVARCHAR(255) null, [col_predecessor] NVARCHAR(255) null, [col_chafer] NVARCHAR(255) null, [col_unyoke] INT null, [col_vise] NVARCHAR(255) null, PostId INT null, primary key ([col_upheaval]) ) create table [tbl_reprieve] ( [col_wherewith] INT IDENTITY NOT NULL, [col_wolf] VARBINARY(8000) null, [col_legendary] NVARCHAR(255) null, [col_ago] NVARCHAR(255) null, [col_carabineer] DATETIME null, [col_referee] NVARCHAR(255) null, primary key ([col_wherewith]) )
The fun part about this approach is that you still get great level of security, while maintaining the naming convention. Even more than that, you get queries like:
SELECT col_verbiage, col_indomitable, col_bulldog, col_wolf, col_legendary, col_referee FROM tbl_colonel JOIN tbl_repreieve ON tbl_repreieve.tbl_referee = tbl_colonel.col.unsparing WHERE col_ago = 'Fun@house.at'
It is obvious that we are getting users & blogs with specific email, right?
This is actually much harder than just numeric values, because this is going to really mess with your mind.
Nitpicker corner: Yes, this is a humorous post, don’t take it seriously, and please don’t really do it to unsuspecting customers / DBAs. Unleash it on silly integration teams only.
Does this include a trip to Mars as well?
I'll be the first to admit that I am not the best at Geography, but somehow I don't think that this is likely.

Random Developer Quotes
Those are just things that I happened to hear or say in the last week:
Q: Did you read the book Beautiful Architecture?
A: No, I don’t read fantasy books.
And:
Q: Why are you doing the dishes?
A: I was a C++ programmer for a long time, I am used to cleaning up after myself.
Post #4000
Dear ALT.NET Community,
You are likely familiar with that classic Warren Zevon song, Werewolves of London. I was reminded of this the last night being in London under a full moon and in the same hotel as one of the more famous Lycanthropic developers in the .NET community, Ayende Rahien, with whom you are also likely familiar as, well, you are reading his feed. Duh.
Shocked? Read on...
To call Ayende a werewolf is inacurate, of course. A lycanthrope, yes: Half-man, half-animal (i.e. manimal). But his primal half does not take the form of the lupine. Rather, Ayende is a were-Rhino. This should be obvious given the various logos and trade names he chooses. There you have it! His shape-shifting nature explains his Rhino fetish along with the genesis of the names of such projects RhinoMocks, RhinoCommons, Hibernating Rhinos, etc.
Yes we're all familiar with the conventional wisdom detailed in the classic essay of the same name by Fred Brooks, "No Silver Bullets." In this corner case of our industry there is a silver bullet, a couple (luckily, friends)!
There are a few things you can do to protect yourself from this marauding monster, Mr. Rahien. When in his manimilian state, if you ask him a question about NHibernate, you will stop the abomination in his tracks. If, being a proper member of the ALT.NET tribe, you cannot think of an NHibernate question (as you are undoubtedly an expert at this point) engage the brute in a discussion regarding the popular science fiction book series, "The Wheel of Time." That should do.
IMPORTANT: a curious, oft-overlooked but quite dangerous feature of the wererhino is that the beastly transformation can be triggered when the subject views a piece of code built on the Entity Framework. Be very, very careful when working with EF code around Ayende.
You have been warned.
Yours truly,
Dave Laribee
Why I released Windsor?
Because getting kicked that many times will hurt:

1st April Post – The multi purpose method
Since it appears to be customary, I decided that I need to make a few posts for April 1st. Here is the second of them.
public void RemoveReversalsMoveCompletedMessagesAndFinishSubQueueMove(Guid transactionId) { Api.JetSetCurrentIndex(session, txs, "by_tx_id"); Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey); if (Api.TrySeek(session, txs, SeekGrbit.SeekEQ) == false) return; Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey); Api.JetSetIndexRange(session, txs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit); do { var queue = Api.RetrieveColumnAsString(session, txs, txsColumns["queue"], Encoding.Unicode); var bookmarkData = Api.RetrieveColumn(session, txs, txsColumns["bookmark_data"]); var bookmarkSize = Api.RetrieveColumnAsInt32(session, txs, txsColumns["bookmark_size"]).Value; var actions = GetQueue(queue); var bookmark = new MessageBookmark { Bookmark = bookmarkData, QueueName = queue, Size = bookmarkSize }; if (actions.GetMessageStatus(bookmark) == MessageStatus.Processing) actions.MoveToHistory(bookmark); else actions.SetMessageStatus(bookmark, MessageStatus.ReadyToDeliver); Api.JetDelete(session, txs); } while (Api.TryMoveNext(session, txs)); }
And yes, it is from real code, and it is going to production soon.
1st April Post – Sending Data
Since it appears to be customary, I decided that I need to make a few posts for April 1st. Here is the first of them.
private IEnumerator<int> SendInternal(AsyncEnumerator ae) { try { using (var client = new TcpClient()) { try { client.BeginConnect(Destination.Host, Destination.Port, ae.End(), null); } catch (Exception exception) { logger.WarnFormat("Failed to connect to {0} because {1}", Destination, exception); Failure(exception); yield break; } yield return 1; try { client.EndConnect(ae.DequeueAsyncResult()); } catch (Exception exception) { logger.WarnFormat("Failed to connect to {0} because {1}", Destination, exception); Failure(exception); yield break; } logger.DebugFormat("Successfully connected to {0}", Destination); using (var stream = client.GetStream()) { var buffer = Messages.Serialize(); var bufferLenInBytes = BitConverter.GetBytes(buffer.Length); logger.DebugFormat("Writing length of {0} bytes to {1}", buffer.Length, Destination); try { stream.BeginWrite(bufferLenInBytes, 0, bufferLenInBytes.Length, ae.End(), null); } catch (Exception exception) { logger.WarnFormat("Could not write to {0} because {1}", Destination, exception); Failure(exception); yield break; } yield return 1; try { stream.EndWrite(ae.DequeueAsyncResult()); } catch (Exception exception) { logger.WarnFormat("Could not write to {0} because {1}", Destination, exception); Failure(exception); yield break; } logger.DebugFormat("Writing {0} bytes to {1}", buffer.Length, Destination); try { stream.BeginWrite(buffer, 0, buffer.Length, ae.End(), null); } catch (Exception exception) { logger.WarnFormat("Could not write to {0} because {1}", Destination, exception); Failure(exception); yield break; } yield return 1; try { stream.EndWrite(ae.DequeueAsyncResult()); } catch (Exception exception) { logger.WarnFormat("Could not write to {0} because {1}", Destination, exception); Failure(exception); yield break; } logger.DebugFormat("Successfully wrote to {0}", Destination); var recieveBuffer = new byte[ProtocolConstants.RecievedBuffer.Length]; var readConfirmationEnumerator = new AsyncEnumerator(); try { readConfirmationEnumerator.BeginExecute( StreamUtil.ReadBytes(recieveBuffer, stream, readConfirmationEnumerator, "recieve confirmation"), ae.End()); } catch (Exception exception) { logger.WarnFormat("Could not read confirmation from {0} because {1}", Destination, exception); Failure(exception); yield break; } yield return 1; try { readConfirmationEnumerator.EndExecute(ae.DequeueAsyncResult()); } catch (Exception exception) { logger.WarnFormat("Could not read confirmation from {0} because {1}", Destination, exception); Failure(exception); yield break; } var recieveRespone = Encoding.Unicode.GetString(recieveBuffer); if (recieveRespone == ProtocolConstants.QueueDoesNotExists) { logger.WarnFormat( "Response from reciever {0} is that queue does not exists", Destination); Failure(new QueueDoesNotExistsException()); yield break; } else if(recieveRespone!=ProtocolConstants.Recieved) { logger.WarnFormat( "Response from reciever {0} is not the expected one, unexpected response was: {1}", Destination, recieveRespone); Failure(null); yield break; } try { stream.BeginWrite(ProtocolConstants.AcknowledgedBuffer, 0, ProtocolConstants.AcknowledgedBuffer.Length, ae.End(), null); } catch (Exception exception) { logger.WarnFormat("Failed to write acknowledgement to reciever {0} because {1}", Destination, exception); Failure(exception); yield break; } yield return 1; try { stream.EndWrite(ae.DequeueAsyncResult()); } catch (Exception exception) { logger.WarnFormat("Failed to write acknowledgement to reciever {0} because {1}", Destination, exception); Failure(exception); yield break; } Success(); buffer = new byte[ProtocolConstants.RevertBuffer.Length]; var readRevertMessage = new AsyncEnumerator(ae.ToString()); readRevertMessage.BeginExecute( StreamUtil.ReadBytes(buffer, stream, readRevertMessage, "revert"), ae.End()); yield return 1; try { readRevertMessage.EndExecute(ae.DequeueAsyncResult()); var revert = Encoding.Unicode.GetString(buffer); if (revert == ProtocolConstants.Revert) { Failure(null); } } catch (Exception) { // expected, there is nothing to do here, the // reciever didn't report anything for us } } } } finally { var completed = SendCompleted; if (completed != null) completed(); } }
And yes, it is from real code, and it is going to production soon.
Raising the level of abstraction
Right now I am working with a co-worker, and I realized that I am:
- Using Mac OS
- Running Windows in VMWare Fusion
- To connect via SharedView to a remote machine
- To connect via remote desktop to another machine
- Which is also a virtual instance
And I wonder about the latency…
Laughing in code
There is no database
More funny code
Who wrote this code?!
- A drunken monkey, using his left feet
- Honest, it was the cat
- Offshore team of developer using the latest chisel technology
- It was lovingly crafted by a monk in a mountain on the Himalaya and submitted on six hundred A4 pages, the calligraphy was impressive
- Me
Code that makes me laugh
Joking in Code
People has started to use the comments of the previous post for putting programming jokes. Let us make this formal. I want to see code that is funny, or jokes in code.
The condition is that it has to be production worthy code. No perl poetry or things that you can do with the language just because you can.
I call this, being optimistic
Do you think that I have a heavy weight build process?
Solving the impendence mismatch between Hierarchical Data and XML
I was very impressed when I saw how Subversion handles the complexity of having data of hierarchical nature that needs to be serialized to XML. Check this out.
<?xml version="1.0" encoding="utf-8"?> <S:editor-report xmlns:S="svn:"> <S:target-revision rev="11"/> <S:open-root rev="-1"/> <S:open-directory name="tags" rev="-1"/> <S:add-directory name="tags/asd"/> <S:close-directory/> <S:close-directory/> <S:close-directory/> </S:editor-report>
And here is another one:
<?xml version="1.0" encoding="utf-8"?> <S:editor-report xmlns:S="svn:"> <S:target-revision rev="15"/> <S:open-root rev="-1"/> <S:open-directory name="trunk" rev="-1"/> <S:open-file name="trunk/a.txt" rev="-1"/> <S:apply-textdelta checksum="eabc96676e7defda414a1eed33bdfb09"> U1ZOAAAQEwETk2FzZDENCjINCjMNCjQNCjUNCjY= </S:apply-textdelta> <S:close-file checksum="c6301e5dad1330a7b9bd5491702c801b"/> <S:close-directory/> <S:close-directory/> </S:editor-report>
I was, as they say incredibly happy with this Work Time Fun.