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,185
Privacy Policy · Terms
filter by tags archive
time to read 5 min | 814 words

Originally posted at 3/30/2011

Remember, we are running on an action scoped session, and this is the code that we run:

public class HomeController : SessionController
{
    public ActionResult Blog(int id)
    {
        var blog = Session.Get<Blog>(id);

        return Json(blog, JsonRequestBehavior.AllowGet);
    }
}

The error that we get is a problem when trying to serialize the Blog. Let us look again the the class diagram:

image

As you can see, we have a collection of Users, but it is lazily loaded. When the Json serializer (which I use instead of writing a view, since it makes my life easier) touches that property, it throws, because you cannot iterate on a lazily loaded collection when the session has already been closed.

One option that we have is to modify the code for Blog like so:

public class Blog
{
    public virtual int Id { get; set; }

    public virtual string Title { get; set; }

    public virtual string Subtitle { get; set; }

    public virtual bool AllowsComments { get; set; }

    public virtual DateTime CreatedAt { get; set; }

    [ScriptIgnore]
    public virtual ISet<User> Users { get; set; }

    public Blog()
    {
        Users = new HashedSet<User>();
    }
}

I don’t like it for several reasons. First, and least among them, serialization duties aren’t one of the responsibilities of the domain model. Next, and most important, is the problem that this approach is incredibly brittle. Imagine what would happen if we added a new lazily loaded property. Suddenly, unless we remembered to add [ScriptIgnore] we would break everything that tried to serialize a Blog instance.

I much rather use an approach that wouldn’t break if I breathed on it. Like the following:

public class HomeController : SessionController
{
    public ActionResult Blog(int id)
    {
        var blog = Session.Get<Blog>(id);

        return Json(new
        {
            blog.AllowsComments,
            blog.CreatedAt,
            blog.Id,
            blog.Subtitle
        }, JsonRequestBehavior.AllowGet);
    }
}

By projecting the values out into a known format, we can save a lot of pain down the road.

But wait a second, this looks quite familiar, doesn’t it? This is the view model pattern, but we arrived at it through an unusual journey.

I don’t really care if you are using anonymous objects or named classes with something like AutoMapper, but I do think that a clear boundary make it easier to work with the application. And if you wonder why you need two models for the same data, the avoidance of accidental queries and the usage of the action scoped session is another motivator.

time to read 1 min | 194 words

Originally posted at 3/30/2011

Previous, our HomeController looked like this:

public class HomeController : SessionController
{
    public ActionResult Blog(int id)
    {
        var blog = Session.Get<Blog>(id);

        return Json(blog, JsonRequestBehavior.AllowGet);
    }
}

My model is defined as:

image

Remember that the previous post we have changed the session management from the request scope to the action scope?

Well, that meant that we have just broken this code…

But can you see how?

time to read 4 min | 795 words

Originally posted at 3/30/2011

In the previous posts, we have looked at how we are going to setup an application using NHibernate. We set it up using:

    public MvcApplication()
    {
        BeginRequest += (sender, args) =>
        {
            CurrentSession = sessionFactory.OpenSession();
        };
        EndRequest += (o, eventArgs) =>
        {
            var session = CurrentSession;
            if (session != null)
            {
                session.Dispose();
            }
        };
    }

But this code is problematic. It is problematic because the session is open for the lifetime of the request. That is a problem, but probably not because of what you think. The #1 reason for issues like Select N+1 is people accessing lazy loaded properties in the views.

One good way of avoiding that is limiting the session scope only to the action, so when rendering the view, the session is not available. Therefor, every attempt to lazy load, will immediately throw. With ASP.Net MVC, this is very easy:

public class NHibernateActionFilter : ActionFilterAttribute
{
    private static readonly ISessionFactory sessionFactory = BuildSessionFactory();

    public static ISession CurrentSession
    {
        get { return HttpContext.Current.Items["NHibernateSession"] as ISession; }
        set { HttpContext.Current.Items["NHibernateSession"] = value; }
    }

    private static ISessionFactory BuildSessionFactory()
    {
        return new Configuration()
            .Configure()
            .BuildSessionFactory();
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        CurrentSession = sessionFactory.OpenSession();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

        var session = CurrentSession;
        if (session != null)
        {
            session.Dispose();
        }
    }
}

We need to modify the SessionController as well, so it would now be:

public class SessionController : Controller
{
     public HttpSessionStateBase HttpSession
     {
          get { return base.Session; }
     }

     public new ISession Session { get { return NHibernateActionFilter.CurrentSession; } }
}

Of course, we have broken the HomeController now, but we will discuss how in the next post.

time to read 2 min | 397 words

Originally posted at 3/30/2011

As I mentioned in the previous post, I don’t really like the code as written, so let us see what we can do to fix that. For a start, we have this code:

public class HomeController : Controller
{
    public ActionResult Blog(int id)
    {
        var blog = MvcApplication.CurrentSession.Get<Blog>(id);

        return Json(blog, JsonRequestBehavior.AllowGet);
    }
}

I don’t like the global reference in this manner, so let us see what we can do about it. The easiest way would be to just hide it very well:

public class HomeController : SessionController
{
    public ActionResult Blog(int id)
    {
        var blog = Session.Get<Blog>(id);

        return Json(blog, JsonRequestBehavior.AllowGet);
    }
}

public class SessionController : Controller
{
    public HttpSessionStateBase HttpSession
    {
        get { return base.Session;  }
    }

    public new ISession Session
    {
        get { return MvcApplication.CurrentSession; }
    }
}

So that result in nicer code, the architecture is pretty much the same, but we have a much nicer code for al of our controllers.

We are not done yet, though.

time to read 3 min | 584 words

Originally posted at 3/30/2011

This is part of an exercise that I give in my course. The context is an MVC3 ASP.Net application. Here is how we start things:

public class MvcApplication : System.Web.HttpApplication
{
    private static readonly ISessionFactory sessionFactory = BuildSessionFactory();

    public static ISession CurrentSession
    {
        get{ return HttpContext.Current.Items["NHibernateSession"] as ISession;}
        set { HttpContext.Current.Items["NHibernateSession"] = value; }
    }

    public MvcApplication()
    {
        BeginRequest += (sender, args) =>
        {
            CurrentSession = sessionFactory.OpenSession();
        };
        EndRequest += (o, eventArgs) =>
        {
            var session = CurrentSession;
            if (session != null)
            {
                session.Dispose();
            }
        };
    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

    private static ISessionFactory BuildSessionFactory()
    {
        return new Configuration()
            .Configure()
            .BuildSessionFactory();
    }
}

And in the controller, we have something like this:

public class HomeController : SessionController
{
    public ActionResult Blog(int id)
    {
        var blog = MvcApplication.CurrentSession.Get<Blog>(id);

        return Json(blog, JsonRequestBehavior.AllowGet);
    }
}

This code is valid, it works, it follows best practices and I actually recommend using something very similar here.

It also annoyed me when I wrote it now, enough to write a series of blog posts detailing how to fix this.

time to read 3 min | 451 words

Originally posted at 3/28/2011

When you assume, you are making an ass out of yourself, you stupid moronic idiot with no sense whatsoever. The ass in question, if anyone cares to think about it, is yours truly.

Let us take a look at the following code snippet:

var concurentDictionary = new ConcurrentDictionary<int, int>();
var w = new ManualResetEvent(false);
int timedCalled = 0;
var threads = new List<Thread>();
for (int i = 0; i < Environment.ProcessorCount; i++)
{
    threads.Add(new Thread(() =>
    {
        w.WaitOne();
        concurentDictionary.GetOrAdd(1, i1 =>
        {
            Interlocked.Increment(ref timedCalled);
            return 1;
        });
    }));
    threads.Last().Start();
}

w.Set();//release all threads to start at the same time
foreach (var thread in threads)
{
    thread.Join();
}

Console.WriteLine(timedCalled);

What would you say would be the output of this code?

Well, I assumes that it would behave in an atomic fashion, that the implementation is something like:

if(TryGetValue(key, out value))
   return value;

lock(this)
{
   if(TryGetValue(key, out value))
      return value;

   AddValue( key, valueFactory());
}

Of course, the whole point of the ConcurentDictionary is that there are no locks. Well, that is nice, except that because I assumed that the call is only made once, I called that with a function that had side effects when called twice.

That was a pure hell to figure out, because in my mind, of course that there was no error with this function.

time to read 9 min | 1679 words

Originally posted at 3/24/2011

One of the common problems with people coming over to RavenDB is that they still think in relational terms, and implicitly accept relational limitations. The following has been recently brought up at a client meeting. The problem was that they got an error when rendering a page similar to that:

The error is one of RavenDB’s Safe-By-Default, and is triggered when you are making too many calls. This is usually something that you want to catch early, and fail fast rather than add additional load to the system. But the problem that the customer was dealing with is that they needed to display different icons for each level of the tree, depending if the item was a container or a leaf.

Inside Raven, categories were modeled as:

{ // categories/1
  "ParentId": null,
  "Name": "Welcome ..."
}

{ // categories/2
   "ParentId": "categories/1",
   "Name": "Chapter 2..."
}

They had a few more properties, but none that really interests us for this post. The original code was pretty naïve, and did something like:

public IEnumerable<TreeNode> GetNodesForLevel(string level)
{
  var categories = from cat in session.Query<Category>()
                   where cat.ParentId == level
                   select cat;
                   
  foreach(var category in categories)
  {
    var childrenQuery = from cat in session.Query<Category>()
                         where cat.ParentId == category.Id
                         select cat;
                         
     yield return new TreeNode
     {
      Name = category.Name,
      HasChildren = childrenQuery.Count() > 0
     };
  }
}

As you can imagine, this has caused some issues, because we have a classic Select N+1 here.

Now, if we were using SQL, we could have done something like:

select *, (select count(*) from Categories child where child.ParentId = parent.Id)
from Categories parent
where parent.ParentId = @val

The problem there is that this is a correlated subquery, and that can get expensive quite easily. Other options include denormalizing the count into the Category directly, but we will ignore that.

What we did in Raven is define a map/reduce index to do all of the work for us. It is elegant, but it requires somewhat of a shift in thinking, so let me introduce that one part at a time:

from cat in docs.Categories 
let ids = new [] 
{ 
    new { cat.Id, Count = 0, cat.ParentId }, 
    new { Id = cat.ParentId, Count = 1, ParentId = (string)null } 
} 
from id in ids 
select id 

We are doing something quite strange, we need to project two items for every category. The syntax for that is awkward, I’ll admit, but it is pretty clear what is going on in here.

Using the categories shown above, we get the following output:

{ "Id": "categories/1", "Count" = 0, ParentId: null }
{ "Id": null, "Count" = 1, ParentId: null }

{ "Id": "categories/2", "Count" = 0, ParentId: "categories/1" }
{ "Id": "categories/1",  "Count" = 1, ParentId: null }

The reason that we are doing this is that we need to be able to aggregate across all categories, whatever they are in a parent child relationship or not. In order to do that, we project one record for ourselves, with count set to zero (because we don’t know that we are anyone’s parents) and one for our parent. Note that in the parent case, we don’t know what his parent is, so we set it to null.

The next step is to write the reduce part, which runs over the results of the map query:

from result in results
group result by result.Id into g 
let parent = g.FirstOrDefault(x=>x.ParentId != null)
select new 
{ 
     Id = g.Key, 
     Count = g.Sum(x=>x.Count), 
     ParentId = parent == null ? null : parent.ParentId
}

Here you can see something quite interesting, we are actually group only on the Id of the results. So given our current map results, we will have three groups:

  • Id is null
  • Id is “categories/1”
  • Id  is “categories/2”

Note that in the projection part, we are trying to find the parent for the current grouping, we do that by looking for the first record that was emitted, the one where we actually include the ParentId from the record. We then use count to check how many children a category have. Again, because we are emitting a record with Count equal to zero for the each category, they will be included even if they don’t have any children.

The result of all of that is that we will have the following items indexed:

{ "Id": null, "Count": 1, "ParentId": null }
{ "Id": "categories/1", "Count": 1, "ParentId": null }
{ "Id": "categories/2", "Count": 0, "ParentId": "categories/1" }

We can now query this index very efficiently to find who are the children of a specific category, and what is the count of their children.

How does this solution compare to writing the correlated sub query in SQL? Well, there are two major advantages:

  • You are querying on top of the pre-computed index, that means that you don’t need to worry about things like row locks, number of queries, etc. Your queries are going to be blazing fast, because there is no computation involved in generating a reply.
  • If you are using the HTTP mode, you get caching by default. Yep, that is right you don’t need to do anything, and you don’t need to worry about managing the cache, or deciding when to expire things, you can just take advantage on the native RavenDB caching system, which will handle all of that for you.

Admittedly, this is a fairly simple example, but using similar means, we can create very powerful solutions. It all depends on how we are thinking on our data.

time to read 1 min | 108 words

Originally posted at 3/22/2011

We recently got a few more employees to Hibernating Rhinos, and I noticed something that was very amusing. It wasn’t really intentional, really, but both new developers had pushed code that went into production on the first day on the job.

In contrast, when I got into my new job in 2005, I started a project that by September of 2009, still haven’t been able to go into production (and to my knowledge, still isn’t in production and likely never will).

It does make one more cautious, I’ll admit, but “every push is a production release” has paid up many times over.

time to read 6 min | 1055 words

Originally posted at 3/22/2011

It has been suggested that I’ll look at a more modern implementation of SharpArchitecture, and I was directed toward the MultiTenant project.

The first thing to notice is the number of projects. It is actually hard to keep the number of projects down, as I well know, but this has several strange choices.

image

I am not really sure what is the point in separating the controllers into a separate assembly, or why we have a separate project for the ApplicationServices.

I am not the only one thinking so, I think:

image

Smile

Then there is the Core project:

image

Personally, I wouldn’t create a project for just two files, but I can live with that. I don’t like attributes like DomainSignature. It is hard for me to really say what, except that I think that they encourage a way of thinking that puts the model in the Center of All Things. I am usually much more interested in what something is doing than how it is shaped.

The data project is mostly concerned with setting up NHibernate via Fluent NHibernate.

Next up is the Framework project. And there we run into the following marker interfaces. I really don’t like marker interfaces, and having those here doesn’t seem to be adding anything important to the application.

image

It seems that there is a lot going on simply to try to get a fallback to a non tenant situation, but the problem here is that it is usually much better to be explicit about those sort of things. You have the CentralSession, and you have the TenantSession, and you are working with each in a different manner. It makes the infrastructure easier to manage and usually result in code that is clearer to follow.

So far, it has all been pretty much uninteresting, I would strongly encourage merging the solution into just two projects, the web & the tests projects, but that is about it.

Now we move into the fancy bits, the controllers project. And there we find the following piece of code:

public class TenantListQuery : NHibernateQuery, ITenantListQuery
{
  public IPagination<TenantViewModel> GetPagedList(int pageIndex, int pageSize)
  {
    var query = Session.QueryOver<Tenant>()
      .OrderBy(customer => customer.Name).Asc;

    var countQuery = query.ToRowCountQuery();
    var totalCount = countQuery.FutureValue<int>();

    var firstResult = (pageIndex - 1) * pageSize;
    TenantViewModel viewModel = null;
    var viewModels = query.SelectList(list => list
                            .Select(mission => mission.Id).WithAlias(() => viewModel.Id)
                            .Select(mission => mission.Name).WithAlias(() => viewModel.Name)
                            .Select(mission => mission.Domain).WithAlias(() => viewModel.Domain)
                            .Select(mission => mission.ConnectionString).WithAlias(() => viewModel.ConnectionString))
      .TransformUsing(Transformers.AliasToBean(typeof(TenantViewModel)))
      .Skip(firstResult)
      .Take(pageSize)
      .Future<TenantViewModel>();

    return new CustomPagination<TenantViewModel>(viewModels, pageIndex, pageSize, totalCount.Value);
  }
}

I quite like this code. It is explicit about what it is doing. There is a good reason to hide this sort of thing behind a class, because while it is easy to read, it is also a lot of detailed code that should be abstracted. I like the use of futures to reduce the number of queries, and that we have explicit paging here. I also like the projection directly into the view model.

What I don’t like is that I really don’t understand how the Session instance is being selected. Oh, I understand how MultiTenantSessionFactoryKeyProvider is working, and that we get the central database because we aren’t using a tenanted entity, but it still seems too much magic here I would rather a CentralSession instead.

Another thin that I liked was the code structure:

image

All of the code is grouped by feature in a very nice fashion.

My main peeve with the application is that this is basically it. We are talking about an application that is basically two CRUD pages, nothing more. Yes, it is a sample app to show something very specific, but I would have liked to see some more meat there to look at.

Multi tenancy is a hard problem, and this application spend quite a bit of time doing what is essentially connection string management.

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
}