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,565
|
Comments: 51,184
Privacy Policy · Terms
filter by tags archive
time to read 23 min | 4457 words

First, let me describe the scenario, I am using Object Builder in a web application to manage the services of the application. Under load, we started to get exceptions from deep within Object Builder. I should also preface this by saying that I have very little knowledge of Object Builder and it is entirely possible that I am commiting some grave error in using it.

Anyway, here is a simple wrapper for Object Builder:

public class BuilderHelper

{

    private Locator _locator = null;

 

    public BuilderHelper():this(new Locator())

    {

    }

    public BuilderHelper(Locator locator)

    {

        this._locator = locator;

        if (!_locator.Contains(typeof(ILifetimeContainer)))

            _locator.Add(typeof(ILifetimeContainer), new LifetimeContainer());

     

    }

 

    public T Build<T>()

    {

        BuilderStrategyChain chain = new BuilderStrategyChain();

        chain.Add(new SingletonStrategy());

        chain.Add(new CreationStrategy());

        PolicyList policies = new PolicyList();

 

        policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy());

 

        BuilderContext builderContext = new BuilderContext(chain, _locator, policies);

        T result;

        result = (T)builderContext.HeadOfChain.BuildUp(builderContext, typeof(T), null, null);

        return result;

 

    }

}

And here is the client code:

[TestClass]

public class StressTestingFixture

{

    private int count = 1000;

 

    [TestMethod]

    public void SimulateHeavyLoad()

    {

        ArrayList list = ArrayList.Synchronized(new ArrayList());

        ManualResetEvent wait = new ManualResetEvent(false);

        Locator locator = new Locator();

        WaitCallback callback = delegate

        {

            wait.WaitOne();//This is required so there will be a lot of threads creating objects at the same time

            try

            {

                BuilderHelper builder = new BuilderHelper(locator);

                Something i1 = builder.Build<Something>();

                if (count % 7 == 0)//need to make sure that GC Collection occurs, so it would clear the WeakRefDictionary

                    GC.Collect(2);

            }

            catch (Exception e)

            {

                string txt = e.ToString();

                Console.WriteLine(txt);

                list.Add(txt);

            }

            finally

            {

                Interlocked.Decrement(ref count);

            }

        };

        for (int i = 0; i < count; i++)

        {

            ThreadPool.QueueUserWorkItem(callback);

        }

        wait.Set();

        while (count > 0 && list.Count == 0)

            Thread.Sleep(15);

        if (list.Count > 0)

        {

            Assert.Fail((string)list[0]);

        }

    }

 

    private class Something

    {

    }

}

The error I am getting:

Assert.Fail failed. System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at Microsoft.Practices.ObjectBuilder.WeakRefDictionary`2.Add(TKey key, TValue value) in C:\Documents and Settings\orene\Desktop\Microsoft Enterprise Library January 2006\src\ObjectBuilder\Utility\WeakRefDictionary.cs:line 82
   at Microsoft.Practices.ObjectBuilder.Locator.Add(Object key, Object value) in C:\Documents and Settings\orene\Desktop\Microsoft Enterprise Library January 2006\src\ObjectBuilder\Location\Locator.cs:line 59
   at BuilderHelper..ctor(Locator locator) in C:\Documents and Settings\orene\Desktop\Microsoft Enterprise Library January 2006\UnitTests\ObjectBuilder\BuilderFixture.cs:line 42
   at StressTestingFixture.<>c__DisplayClass1.<SimulateHeavyLoad>b__0(Object ) in C:\Documents and Settings\orene\Desktop\Microsoft Enterprise Library January 2006\UnitTests\ObjectBuilder\StressTestingFixture.cs:line 80

To say that this is worrying is a major understatement...

Any EntLib experts that can shed some light into this?

time to read 2 min | 218 words

Since I was asked, here is a demo application for using Active Record and Repository<T>.  Please note that this is an internal application that I use to merely test some ideas, so it is a bit rough, and there isn't any real functionality.

  • The more interesting stuff for ActiveRecord & Repository<T> can be found in the FaqController.
  • The entities are in Exesto.Model assembly, with all the usual attributes.
  • A UnitOfWorkApplication (HttpApplication) handles the scopes (using IUnitOfWorkFactory).
  • Configuring Windsor is done using Binsor, in Windsor.boo
  • Visit /construct/database.rails to create the database.

Here are the links to the source online:

time to read 6 min | 1091 words

Note: I just spend quite a bit time writing this, I am putting it on my blog so I will remember it exsts.

Who am I?

Oren Eini is a senior developer in We!, a consulting group based in Israel, focusing on architecture, data access and best practices. Most often, he is working on building complex business systems using .Net 2.0, NHibernate and Castle's Frameworks. Oren is an active member in several Open Source projects, including (but not limited :-) ) NHibernate, Castle and Rhino Mocks. He has a blog at http://www.ayende.com/Blog/ where he publish his thought every once in a while.


Level 4/300: Object Relational Mapping += 2: More then just data <-> object

Object relational mapping are becoming only more popular, as people developing complex systems find that they need more than the tabular model to work with in their applications. A sophisticated ORM can do a lot more than merely get the data out of the database in object form, it can be a valuable assest in simplifying development and making things possible. In this session, you will see how you can utilize an ORM in untraditional ways to get an additional, better, approach to solving complex issues.
Some of those ways include business rules, localization, state transitions, inversion of control, etc. All done via the ORM layer, and all can be used to drasticly simplify the complexity of the given scenarios.


Level 100: Using Active Record to write less code


What would you say if I told you that you can stop writing data access code in .Net? Aren't you tired of writing the same thing over and over again, opening connection, querying the database, figuring out what to return, getting back untype data that you need to start putting on the form? Do you really see some value in writing yet another UPDATE statement?
The Active Record framework allows you to fully utilize the power of the database, but without the back breaking work that it used to take. Active Record uses .Net objects to relieve you from the repeating task of persistance. Those objects are schema aware and can persist and load themselves without you needing to write a single line of SQL. Building business application using Active Record is a pleasure, the database stuff just happens, and you are free to implement the business functionality.

Presentation for this can be found here: http://www.ayende.com/91/section.aspx/download/160

Level 200: Rapid (maintainable) web development with MonoRail


If you're a fan of Ruby on Rails and want to see similar capabilities in .NET, or you're an ASP.NET developer looking for an easier way to do things, MonoRail will be irresistible once you find out what it can do for you. Strong support for Ajax makes writing buzzward compliant web applications a breeze. Utilization of the Model-View-Controller architecture and convention over configuration makes web development with MonoRail a pleasure. Free yourself from page-life cycle issues and viewstate worries, start working with MonoRail, where the framework works for you.
This talk will introduce the general concepts of the framework, and how you can use them

Level 100: Interaction based testing With Rhino Mocks

Beyond the simplest scenarios, all objects had collaborators that they work with. This flies in the face of testing objects in isolation. This is the problem that mock objects were created to solve. In this talk you will learn what mock objects are, how to utilize them and best practices on when / how to utilize them. Rhino Mocks is a mock objects framework for .Net whose core goals are to let the developer rely on the compiler work well with refactoring tools.

Level 200: Inversion of Control and Dependency Injection: Breaking out from the dependecy hell

Responding to change is the holy grail of software development. Inversion of Control (IoC) and Dependency Injection (DI) are two related patterns that allows to make significant changes to an application without having to touch every part of the application. IoC and DI encourage breaking the application into discerete, highly cohesive parts, so a change, when it eventually comes, is very local. A nice benefit is that applications that uses IoC are also very testable applications.
This talk will introduce the concepts of IoC and how to use them in your application.

Presentation can be found here: http://www.ayende.com/91/section.aspx/download/145

Level 4/300: Advnace usages of Inversion of Control containers

You already understand the concepts of Inversion of Control and Dependency Injection, now is the time to see how far we can make the IoC container works for us. This talk will focus on using an IoC container in complex scenarios. We will talk about generic decorator chains and generic specialization, contextful containers and IoC DSLs. These powerful concepts can greatly enhance your ability to respond to change in your application.

Level 300: Writing Domain Specific Languages in Boo

Domain Specific Langauge is not just the DSL SDK from Microsoft. A DSL can make working with the domain much easier, since you are capable of leveraging the domain concepts directly. The other alternative to a DSL is an XML file, and we all know how well declarative model can work when you need imperative concepts, just consider NAnt for a minute and you will see the issue. Usually, writing a DSL in .Net would be a complex issue, requiring writing a parser, interpreter, etc. Boo already handles all of that, and its open architecture means that it is very easy to extend it to express the concepts of the domain. This talk will show you how to build DSLs in Boo and how to utilize this power in your applications.
time to read 3 min | 546 words

I was urgently called today to solve a problem in one of my applications. The problem was that for some reason, the application would stop process incoming files, a restart would fix this issue for a short while, after which the problem would re-appear. The application is heavily multi threaded, and has a lot of logging built in to help diagnose issues that may crop up.

The problem is that the problem never even showed up in the logs. It was as if the application stopped watching the directory, but it should never do that. I began to consider framework bugs and was about to start investigating how to investigate this issue when I noticed a recurring pattern in the logs:

Cycle #123:
Checking status of Item #42: Not yet ready
Checking status of Item #43: Not yet ready
Checking status of Item #44: Not yet ready
Checking status of Item #45: Not yet ready
Checking status of Item #46: Not yet ready

Cycle #124:
Checking status of Item #42: Not yet ready
Checking status of Item #43: Not yet ready
Checking status of Item #44: Not yet ready
Checking status of Item #45: Not yet ready
Checking status of Item #46: Not yet ready

Hm... an item is sent to another machine for processing, and the communication between the two parts is done via a web service, on a fairly slow connection.

What happened was interesting, there was a large number of items that has not been processed yet, and at every cycle (~1 minute) all of them were checked indepdently. The problem was that when it got to the point where enough of them were being queries, the next cycle began before the first one could begin.

Since checking the status of all the items was done on a thread pool thread, and since processing a new item (and logging it) also accurrs on a thread pool thread. After the application has been running for a while, asking the second server for status starts to consume most of the thread pool threads, and processing of new items is delayed until their turn in the queue arrives (although that is not guranteed).

The "fix": change the cycle time for checking status to 10 minutes and asking the other side to start processing this on more than a dialy basis.

time to read 10 min | 1970 words

Please note that this is no longer supported behavior in NHibernate 2.1 and up. It was a hack to begin with, and it isn't guaranteed to continue working.

I can't think of a good name for this post, but it is a very cool discovery. First, let us examine the scenario, a customer of mine has bought a database of localized data, which had the following structure:

(Image from clipboard).png

Now, what the customer wanted to be able to do is something like this:

Product product = session.Get<Product>(5);
productName.Text = product.Name;

And get the correct name for the user's culture. In addition to that, they didn't want to have to load the all the product names collection and get the name in memory. The database include several hundred thousnads of products, localized to several languagues, so this is a big perf concern.

I thought about this quite a bit, and was nearly at the point where I told them that it can't be done when I recalled that NHibernate 1.2 added filters capabilities. A quick testing proved that it is possible to do this with NHibernate, using the following approach:

First, we need to map the product, like this:

<class name='Product'>

       <id name='Id'

              column='id'>

              <generator class='native'/>

       </id>

       <property name='Amount'/>

       <property name='Size'/>

       <property name='Name'

                       formula='(SELECT ProductNames.Name FROM ProductNames

                       WHERE ProductNames.Id = id and ProductNames.CultureId = :CultureFilter.CultureId)'/>

</class>

Please note the Name property, we map it using a formula, which is just a piece of SQL that we put in the mapping. The new thing here is that we can refer to :CultureFilter.CultureId in the formula. Where does it come from? As you can see above, we need this to be transparent to the developer when using the code.

The secret is in the following bit of mapping:

<filter-def name='CultureFilter'>

       <filter-param name='CultureId' type='System.Int32'/>

</filter-def>

Here we define a filter, which takes parameters, usually a class will use the filter-def parameters to express a filter according to this parameters. But we don't want to filter the results, we want to just have it happen. It turns out to be that using the full name of the filter parameter is something that NHibernate understand anywhere, so...

//This is usually in Application_BeginRequest
session.EnableFilter("CultureFilter").SetParameter("CultureId", Thread.CurrentThread.CurrentCulture.LCID);

Product product = session.Get<Product>(5);
productName.Text = product.Name;

And you get exactly what you wanted! I was very pleased when I was able to come up with such an elegant solution :-D

time to read 2 min | 257 words

In response to a question about why extend NUnit instead of MS Test, Scott Bellware gives one of the most eloquent response that I have seen in a long time.

I personally don't use MS Test.  It's a niche product built by a team that was largely detached from the developer testing community.  It's mostly visual glitz aimed at people who don't really have the experience to be discerning, and who can be manipulated into buying tools by blinking lights and shiny surfaces.  The VSTS product line segmentation is out of touch with the reality of the cross-functional roles that developers are increasingly called to play.  It's way over-priced.

There would be little value in me writing extensions for MS Test.  The limited community of folks who have adopted it are largely following Microsoft's guidance on developer testing and thus are missing the BDD point as widely as Microsoft missed the TDD point.  The open source world is innovating in this space much faster than Microsoft can hope to - both in tooling and the appraches driving the tooling.

The above summarizes my opinions on MS Test much better than I could.

time to read 1 min | 200 words

I am currently thinking about my next project, and I really want to use Active Record, and at the same time, I really want to be able to utilize Repository<T> and decorators chains or not.

A long time ago I made sure that Active Record will be usable without utilizing the "Active Record"-ness of it, so it wasn't that hard to build an IRepository<T> implementation for it, implementing UnitOfWork was a bit more tricky, since I wanted to keep the option to use NHibernate / Active Record at will, as always, another layer of abstraction is always the answer.

I went to such lengths mainly because I didn't want just to get the Active Record RAD capabilities, but to take advantages of the other advantages that it offers (Validation is one, ARDatabind is another, etc). I am not so sure that this is a good idea, though.

I am considerring using Active Record to just generate the mapping (since it has very strong cross-inferencing capabilities), but I am not sure if that is a good idea in the long run...

Any ideas?

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  2. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  3. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
  4. RavenDB 7.0 Released (4):
    07 Mar 2025 - Moving to NLog
  5. Challenge (77):
    03 Feb 2025 - Giving file system developer ulcer
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}