Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,592
|
Comments: 51,223
Privacy Policy · Terms
filter by tags archive
time to read 1 min | 126 words

Rob Conery has just announced that he is going to work for Microsoft. That is interesting, but not really surprising or shocking. Microsoft does seems to hire a lot of the bloggers in the .Net space.

What is surprising is the role that he is expected to fill in Microsoft. He is going to work full time on SubSonic, an Open Source project.

Why is this surprising? Because to date, I haven't heard of any other cases where Microsoft have paid for developers to work full time on OSS that didn't came directly from Microsoft. This is a fairly common model in the OSS world, but this is the first time that Microsoft has made such a move.

Very welcome move from Microsoft, and congratulations to Rob.

time to read 3 min | 573 words

imageSharing common functionality across controllers is something that I have run into several times in the past. It is basically needing to offer the same functionality across different elements in the application.

Let us take for a moment a search page. In my current application, a search page has to offer rich search functionality for the user, the ability to do pattern matching, so given a certain entity, match all the relevant related entities that can fit this entity. Match all openings for a candidate. Match all candidates for an opening.

That is unique, mostly, but then we have a lot of boiler plate functionality, which moves from printing, paging, security, saving the query and saving the results, changing the results, exporting to XML, loading saved queries and saved results, etc, etc etc. Those requirements are shared among several

On the right you can see one solution for this problem, the Template Controller pattern. Basically, we concentrated all the common functionality into the Base Specification Controller.

What you can't see is that the declaration of the controller also have the following generic constraints:

image public class BaseSpecificationController<TSpecification, TEntity> : BaseController
	where TSpecification : BaseSpecification<TEntity>, new()
	where TEntity : IIdentifable

This means that the base controller can perform most of its actions on the base classes, without needing to specialize just because of the different types.

Yes, dynamic language would makes things much easier, I know.

Note that while I am talking about sharing the controller logic here, between several controllers, we can also do the same for the views using shared views. Or not. That is useful if we want to use different UI for the search.

In fact, given that we need to show a search screen, it is not surprising that we would need a different UI, and some different behavior for each search controller, to get the data required to specify a search.

Now that we have the background all set up, let us see what we can do with the concrete search controllers, shall we.

imageYou can see the structure of them on the right. The search candidates is doing much more than the search orders, but a lot of the functionality between the two is shared. And more importantly, easily shared.

Well, if you define the generics syntax above as easy, at least.

The main advantage of this approach is that I can literally develop a feature on the candidates controller, and then generalize it to support all the other searches in the application.

In this scenario, we started with searching for candidates, and after getting the basic structure done, I moved to start working on the search orders.

At the same time, another guy was implementing all the extra functionality (excel export, sending SMS and emails, etc).

After we I finished the search order page, we merged and refactored up most of the functionality that we needed in both places.

This is a good approach if you can utilize inheritance in your favor. But there is a kink, if you want to aggregate functionality from several sources, then you are going to go back to delegation or duplication.

Adam has interesting discussion about this issue, and an interesting proposition. But that will be another post.

Deal Breakers

time to read 2 min | 330 words

Occasionally I get to try something that sounds really good, but it falls on the execution because of the small details. Let us take FireFox Prism as an example. The idea is good, I get a separate fire fox window just for gmail, or other always on apps. Note that I am using it as an example only, because I just run into it. Prism is still in beta, so it is just an example.

This means that if the browser crash I don't lose my unsaved email, and more importantly, I can close FireFox (and thus release the memory) without closing my mail.

Here is why I wouldn't be using it for now:

 image image

Can you spot the difference between the two images?

The Prism one is on the left, FireFox is on the right. The Gmail on Prism doesn't display a caret symbol in Gmail's rich edit box. That is a deal breaker for me, because I can't really type without it.

I. Can't. Type. Without. The. Caret. Period.

The point that I am trying to make is that you need to consider the deal breakers for the user. And even something as small as the caret is a deal breaker.

In my last project, the first release was completely useless to some of the users, because a select list didn't contains all the old values, and we couldn't bring those values, because their presence depended on so many other things. Those users had to wait for the second release to use the application.

Deal breakers are the other side of the killer features, and are just as important when you analyze a solution. Examples of deal breakers in typical software include:

  • Not supporting the old application's keyboard shortcuts
  • Web application replacing local app - latency
  • Different fonts (True story!  Priority 0 bug!)
  • Compatibilities
time to read 3 min | 519 words

The scenario that Christiaan Baes need to solve is reducing the startup time of a Win Forms application. The main issue here is that the initial load of the application should be fast, but in this case, we are feeding NHibernate about a hundred entities, so it take a few seconds to run them.

I asked Christiaan to send me profiler results of the code, and it looked all right on his end, so it was time to look at NHibernate and see what she had to say about that.

The test scenario was startup time for a thousands entities. I think that this is a nice shiny number that probably represent way too much entities per application, but let us go with it.

Initial testing showed that for this amount, we get about 14 seconds startup time, just to get the session factory started. Now that wasn't right, I felt. NHibernate does a lot of reflection on startup, but even so, 14 seconds was quite a bit. A deeper analysis showed that I was wrong, it wasn't reflection that was costing so much, it was actually building the Configuration that took the time, not building the session factory.

Why was it taking so long? Well, NHibernate is using XML for configuration, and that xml is validating using a schema. And that took 11 seconds for a thousand documents.

Problem.

I played a bit with the code, but it remained steady on 11 seconds just for reading the configuration in. Eventually I tried to do merge the 1000 XML documents to a single big document, and that had a significant effect, it dropped the time to just over 3 seconds. To an overall startup time of 5.5 seconds on a 1000 entities session factory.

If you are going in this route, I would strongly suggest that you would do this merging as a pre build step, rather than try to work with a single unwieldy artifact.

Still not good enough, I hear you think, right?

Here are a few other suggestions that are worth keeping in mind:

  • Why are you initializing it on startup? And does it have to be on the main thread? If you can push it to a background thread, then this is usually all that you would need to do.
  • Do you really need all the entities, from the get go? If not, you can create two session factories. One to serve as a fast initializing factory, able to respond to the initial requests. At the same time, initial the global session factory, and then replace them.
  • Do you really need all those entities in a single session factory? If you have a lot of entities, usually this is a sign of several mixed domains that are involved. It would probably be better to split them up to different session factories.

If all of the above still isn't enough for you, the next step is persistable configuration itself (probably using serialization. That is not supported by NHibernate at the moment, although I am more than willing to accept a patch that would add this functionality.

Hope this helps...

Rhino Mocks 3.3

time to read 2 min | 235 words

image Well, it has been a couple of months, but we have a new release of Rhino Mocks. I would like to thank Aaron Jensen, Ivan Krivyakov and Mike Winburn for contributing.

Probably the two big new features is the ability to call void methods using Expect.Call and the ability to use remoting proxies to mock classes that inherit from MarshalByRefObject. Rhino Mocks will now choose the appropriate mocking strategy based on the type you want.

Note: you cannot pass constructor arguments or create partial mocks with remoting proxies.

The change log is:

Bug Fixes: 

  • Fixing inconsistency in how Is.Equals handled ICollection instances, now it will compare them by their values, not their Equals() 
  • Fixing NASTY bug where setup result that were defined in a using(mocks.Ordered()) block were not registered properly. 

Improvments:

  • Changing error message to "are you calling a virtual (C#) / Overridable (VB) method?" - make it friendlier to VB guys. 
  • Exception for Record will not trigger a ReplayAll(), which can mask the exception. 
  • Adding a check for running on Mono to avoid calling Marshal.GetExceptionCode in that case.

New features:

  • Adding support for calling void methods using Expect.Call
  • Adding remoting proxies.
  • Made IMethodOptions generic. Allows compile time type safety on Return. 
  • Adding a PublicFieldConstraint

As usual, you can get it here

time to read 1 min | 73 words

Rob Conery has posted an interesting poem, I wouldn't really mind, except that he posted that in binary, which meant that I really had to figure it out.

Can you resist the urge

1110111 1101000 1111001 100000 1100100 1101001 1100100 100000 1111001 1101111 1110101 100000 1101101 1100001 1101011 1100101 100000 1101101 1100101 100000 1100100 1100101 1100011 1101111 1100100 1100101 100000 1100010 1101001 1101110 1100001 1110010 1111001 100000 1100100 1100001 1110100 1100001 111111

time to read 1 min | 102 words

I am not sure why, but we had some hilarious quotes today at class:

When I talked about Erlang and showed an Erlang echo program in about 20 lines of code.
Student: Echo is a single word in DOS

I was cackling about that for a good five minutes, but this is the one that really had me in stitches:

Student: My wife made my code cleaner, she put periods instead of semi colons and straighten the indentations. She didn't understand why I am so messy when I write, nor why I wasn't happy that she "cleaned it up"

Binsor 2.0

time to read 4 min | 671 words

All credit should go to Craig Neuwirt, for some amazing feats of syntax. He has managed to extend Binsor to include practically all of Windsor's configuration schema. This is important because previously we had to resort to either manual / ugly stuff or go back to XML (see: manual & ugly).

This is important because some of the more interesting things that you can do with Windsor are done using the facilities, and Craig has made sure that Binsor will support the main ones in a natural manner, including out of the box support for the standard configuration model.

Let us start by using the standard configuration model for a moment, the Active Record Integration Facility is expecting to be configured from XML, but we can configure it like this:

facility arintegration, ActiveRecordFacility:
	configuration:
		@isWeb = true, isDebug = true
		assemblies = [ Assembly.Load("My.Assembly") ]
		config(keyvalues, item: add):
			show_sql = true
			command_timeout = 5000
connection.isolation = 'ReadCommitted' cache.use_query_cache = false dialect = 'NHibernate.Dialect.MsSql2005Dialect' connection.provider = 'NHibernate.Connection.DriverConnectionProvider' connection.driver_class = 'NHibernate.Driver.SqlClientDriver' connection.connection_string_name = 'MyDatabase' end end

To compare, here is the equivalent  XML configuration.

<facility id="arintegration" 
	type="Castle.Facilities.ActiveRecordIntegration.ActiveRecordFacility, Castle.Facilities.ActiveRecordIntegration" 
	isWeb="true" 
	createSchema="true">
 <assemblies>
	<item>My.Assembly</item>
 </assemblies>
 <config>
	<add key="hibernate.cache.use_query_cache" value="true" />
	<add key="hibernate.connection.isolation" value="ReadCommitted" />
	<add key="hibernate.show_sql" value="false" />
	<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
	<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
	<add key="hibernate.connection.connection_string_name" value="MyDatabase" />
	<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
 </config>
</facility>

We don't have any significant reduction in the number of lines. This is mostly because we need to specify a lot of items for the facility to work, but we do have significant reduction in the noise that we have to deal with.

But, frankly, this isn't the best sample, let us take a look at the shortcuts that Binsor now provides, shall we?

Event Wiring

XML configuration:

<component 
	id="SimpleListener" 
      type="Castle.Facilities.EventWiring.Tests.Model.SimpleListener, Castle.Facilities.EventWiring.Tests" />

<component 
	id="SimplePublisher" 
      type="Castle.Facilities.EventWiring.Tests.Model.SimplePublisher, Castle.Facilities.EventWiring.Tests" >
      <subscribers>
      	<subscriber id="SimpleListener" event="Event" handler="OnPublish"/>
	</subscribers>
</component>

And the Binsor configuration to match it:

component simple_listener, SimpleListener

component simple_publisher, SimplePublisher:
	wireEvent Publish:
		to @simple_listener.OnPublish

Now that is far clearer, isn't it?

Factory Support

XML configuration:

<component id="mycompfactory" 
      type="Company.Components.MyCompFactory, Company.Components"/>

<component id="mycomp" 
	type="Company.Components.MyComp, Company.Components"
	factoryId="mycompfactory" 
	factoryCreate="Create" />

Binsor configuration:

component mycompfactory, MyCompFactory

component mycomp, MyComp:
	createUsing @mycompfactory.Create

Other new features:

  • Integrating Castle Resources, so now we can use Binsor over several files, which can be located anywhere, including assembly resources, for instance.
  • Easy support for startable and life styles.
  • Extension points for future needs.
time to read 2 min | 391 words

You were just handed a strange DSL implementation, it does stuff, and it may be cool, but you have no idea how it works.

Craig Neuwirt recently did a major overhaul of Windsor ( I am going to post soon with the details of how cool it is now ), but I am now faced with the question, how do you grok such a thing? I thought that it would be useful to put a list of what I am doing to understand how the internals now works.

It goes without saying, but the nitpickers will ask, that a DSL implementation is code like any other, and as such, it can have good & bad implementations. I think that what Craig has done was amazing. It makes for an interesting reading, I actually had to take notes, to make sure that I will not miss any of the cool stuff.

  • Understand the domain.
    This is critical, because if the DSL is chicken scratching to you, you won't be able to get the implementation.
  • Get the tests.
    First things first, make sure that you have tests that ensure that you can understand what the DSL is supposed to do. In addition to that, it allows you to debug a simplified scenario repeatedly, so you can walk through that and figure out what is going on.
  • Take the simplest scenario and run it, then open the resulting DLL in Reflector
    This is important, because you need to be able to see what the differences are between the DSL and the actual executed code are. This allows you to understand in a deep level what the various elements of the language do.
  • Identify a transformation, and follow how it is being built throughout the code
    It will allow you to understand the concepts and patterns used through the code.
  • Follow each transformation throughout its own code path only
    Fairly often you can get side tracked by trying to put the entire program in your head, this is usually not possible, track a single path through the code to completion. After that, you can start tracking other paths, but it is important to have an understanding of the full cycle, and then expand from that.

Hm, not really that different from how I would approach an unfamiliar code base, come to think about it.

FUTURE POSTS

  1. Semantic image search in RavenDB - 2 days from now

There are posts all the way to Jul 28, 2025

RECENT SERIES

  1. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  2. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  3. Webinar (7):
    05 Jun 2025 - Think inside the database
  4. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  5. RavenDB News (2):
    02 May 2025 - May 2025
View all series

Syndication

Main feed ... ...
Comments feed   ... ...
}