Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 5,968 | Comments: 44,488

filter by tags archive

No code today


I feel a burning in my eyes, a pain in my  temples. What can it be? Perhaps it is this code that I just read? Unfortantely I can't post it, but it's a TheDailyWTF candidate for sure. The authors carefuly considered each and every best practice in .Net, and gave them a very careful, very... interesting twist. For instance, on the subject of business objects vs. datasets, the code implements ORM on top of DataSets, Argh! And that isn't the least of it!

So, I'm not going to write any more code today in protest for WTF code everywhere. I actually had a sort of morbid enjoyment watching this code work. I counted a WPM (WTF Per Minute) of ~15, which I believe to be a world record.

Maybe the optimizations could've come a little sooner?


Okay, I'm getting curious about stuff, so I keep the SQL profiler open, and I just saw a single page issue 91(!) SQL statements. Granted, this is a complex page, but I think that I can do it manually with maybe 4 SQL statements (and ~5,000 Line of code to sort it out later).

There are some parts of the code that I really don't know what to do. On the one hand, lazy loading some of the information make sense most of the time, but that may bring me to the horrendous Select N+1 problem.

Right now I'm deferring the decision, I added some lazy attributes, and that reduced the problem somewhat to 72(?!) statements. Still way too high, but this require some thought before acting. I'll let it lie in peace now, while I consider what to do. I also made a huge mistake by not running the test after I changed each relationship to lazy. I got so many errors when I finally did run them that it took me way too long to fix them.

One other thing I discovered, NHibernate assumes that accessing the properties is always safe, and it breaks it pretty badly if you start to mess with uninitialized collections during the initialization process. I reverted back to the old behavior (yes, I'm inconsistent, I know.)  

Giving up on lazy load protections in NHibernate.Generics


Okay, I just run into some head scratching bugs when using NHibernate.Generics. The issue was the well documented edge case, which turn to be a bitch when testing. I might have been able to fix this, but the whole thing pissed me too much when I noticed that it would work in the debugger, but not when running outside of it.

This is a crime that I won't tolerate. If I debug a piece of code, it should bloody well work, and not behave differently. I'll remove it from the code tonight, and hopefully I'll also remember to update the documentation for it. This would make NHibernate.Generics behave identically to the usual NHibernate' collections, which is how it should be.

On Upgrade and Migration


So I was listening to DotNetRocks #115 (with Jackie Goldstein), and part of what they were talking about was the migration wizard that was suppose to migrate VB6 to VB.Net code. One of the thing that they brought up in the talk was that people expected that the wizard will take the code and turn it into a best-practice-using code. One of the examples that they gave was turning VB6 IO to .Net Streams IO (which the migration wizard doesn't do).

I couldn't help thinking about the poor developer who would run this hypothetical wizard and suddenly all his code is transformed from the familiar VB6 code to incomprehensible VB.Net code. I can just feel the anguish of that developer, trying to get the entire framework at once, stumbling along in a suddenly unfamiliar code base.

That is if the wizard was 100% correct, all the time. Occasionally I decide to break away from the base practice in a certain area, usually because I understand what I'm doing, and I know what needs to be done. I would hate to see what a wizard would do to this code.

Rhino Mocks 2.5.3: Out & Ref


This time I actually did nothing for this release. Jeff Brown added support for Out & Ref parameters for Dynamic Proxy, and all I had left to do is hit the build button a couple of times and upload the stuff to the server.

This closes the next to last big problem with Rhino Mocks. The very last one has to do with generic methods, which I hope to be able to fix this week.

 You know the drill, you can download it, or access the source directly.

No More Swapping


I'm getting another 1Gb of RAM tomorrow. My main machine has 1Gb of RAM, and I constantly has to monitor the memory usage because I use a lot of applications simultaneity. Right now I'm using 967Mb:

  • Outlook is the usual culprit, with 91Mb.
  • RssBandit add another 68Mb to the pressure.
  • NAnt is currently compiling Castle, so it's happily eating 110Mb.
  • WBEditor (which I use to write this post) is taking a hefty 59Mb to allow me to do that
  • Firefox is no mincemeat with 55Mb taken.
  • Winword is active because I'm writing a mail message, add another 48Mb to the cake.
  • SQLServer is a modesy 46Mb
  • Explorer is another 30Mb

I'm reporting only the current mem usage, there is also the peak mem usage to consider, since I don't see it being returned the the free memory pool until the process is closed. And I've not even talked about the amount of memory Visual Studio feels free to grab. While I wrote this post the memory usage went up to 1037Mb, the peak memory usage for this machine is 1.5Gb.

I'm pretty pissed that I need to do that, even though the last upgrade I made on this computer was over a year ago, I expect 1Gb to last, damn it. The one thing that I can't stand is when I'm thinking faster than the computer can follow. The problem is that the moment that this starts, I can feel the thoughts going away, and I know that I'm going to lose them while I wait the computer to finish whatever it is that it is doing.

Swapping is a great idea, but it make the computer totally unusable for the user seating in fornt of it. It breaks every assumtion that you have with regard to cheap/costly operations. To everyone who says that memory is cheap, consider this: I'm probably going to break Outlook 2003, since it's not capable of handling more than 1Gb of RAM (but it has a hotfix).

The Silent Exception


What is the most useless, annoying, brainless thing that an application can do? It is to shout: "Error occured". Tell me you haven't ever sat in front of the computer, staring at a completely helpless error, knowing that the program had the information that you need, but it just won't tell you.

I just revised an exception message four times, and on each time, I added more and more information to it.

Here are the iterations:

  • Property must be virtual on classes with lazy loading enabled - This one explain the problem, but doesn't really say what happened to caused it.
  • Property must be virtual on classes with lazy loading enabled [ActiveRecord(Lazy=true)] - This one gives a little more info, now even someone without intimate knowledge of the way ActiveRecord works can just search for it.
  • Property DemoProp must be virtual because the class is lazy loaded [ActiveRecord(Lazy=true)]  - Better, now I've information that says where the error happened. I still don't know in which class this happened, and if this is a common name, I'm still in a problem.
  • Property DemoProp must be virtual because the class DemoClass is loaded loaded [ActiveRecord(Lazy=true)] - Much better, now I know the name of the property and the name of the class, I can easily find it, and fix it.

Any horror stories about silent exceptions? Any way to improve the exception?

BTW, there is another side to the coin, the verbos exception, but that isn't nearly that much of a problem. You can reduce information, but you can create it. On the other hand, the misleading exception is the worst beast of them all.

Why I hate chasing bugs into NHibernate


The issue is not that the code isn't good or that it's complex or that I don't understand it. The issue is that I have to manually move all the references to the complied assembly to the project, and when I'm done, I need to reset all of them back. I'm not using NHibernate alone, but several other libraries that depend on it (ActiveRecord and NHibernate.Generics), which I also need to add to the project, and I need to change their references, etc.

 

I can't even think about keeping them there permanently, I have to track a bug into NHibernate about once a month or so, and the build times are going up when I add all those additional projects. I thought about writing a macro to do this for me, but I don't know enough (or care enough) about VS internals to do it.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
  2. Production postmortem (4):
    23 Jul 2015 - The case of the native memory leak
  3. API Design (7):
    20 Jul 2015 - We’ll let the users sort it out
  4. What is new in RavenDB 3.5 (3):
    15 Jul 2015 - Exploring data in the dark
  5. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats