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 2 min | 290 words

Another interesting problem that I run into in Jamie Farser’s blog, he is building a game and run into a problem designing the object model for it. The problem can be sum up pretty easily in two pictures:

[1.png]

And here is what Jamie has to say about it:

Each interface defines several methods or properties (for example, Attack or AttackRanged). However this feels a bit wrong to me - I'd ideally like just a single Attack method, which would then do something to determine whether the unit was capable of ranged attack

There is another issue here, the object model as it is structured now is fixed. But in most games, units gain additional capabilities as they mature. For example, a spearman may start out as a simple hand to hand unit but be upgraded to a javelin thrower.

This calls for a state pattern, because the state that a unit may be is going to changed over time. More over, I don’t like the idea that we have things like Attack or AttackRanged, it seems to me that the game engine knows way too much about the way that units are operating. I would much rather have something like ExecuteTurn, instead.

That would move the game engine into a simple command executer, and the code inside a a unit to a simple forward to the appropriate state. It seems to be simpler. And upgrading can be done by simply switching the state that you are currently in. It is a remarkably stable design. Something very similar to that is sitting in the heart of most of what Rhino Mocks is doing.

time to read 2 min | 383 words

NHibernate sessions are not thread safe, and attempting to use them in multiple threads requires careful synchronization. It is generally better to consider a session only useful within the thread that created it.

There are valid scenarios for cross thread session usage (background loading with careful sync, multi request spanning session), but the invalid scenarios are far more common.

Let us take a look at the following code:

public class CrossThreadSession : IScenario
{
	public void Execute(ISessionFactory factory)
	{
		using(var session = factory.OpenSession())
		{
			var @event = new ManualResetEvent(false);

			ThreadPool.QueueUserWorkItem(state =>
			{
				using(var tx = session.BeginTransaction())
				{
					session.Get<Blog>(1);

					tx.Commit();
				}

				@event.Set();
			});

			@event.WaitOne();
		}
	}
}

If you’ll try to execute it with NH Prof listening, you are going to see this:

image

NH Prof is properly detecting and warning that we are using a single session in multiple threads.

I did mention that there are valid scenarios for that, so you can either just tell NHibernate to ignore this specific alert by clicking the link, or disable this alert completely if you are doing cross thread session usage extensively and you know it to be safe:

image

Nice enough feature, for about 30 minutes of work. I love working on NH Prof code base.

And just for fun, here is the test for this:

public class DetectCrossThreadSessionUsage : IntegrationTestBase
{
	[Fact]
	public void CanDetectCrossThreadSessionUsage()
	{
		ExecuteScenarioInDifferentAppDomain<CrossThreadSession>();

		var first = model.Sessions.First();

		Assert.Equal(1, first.Statistics.NumberOfStatements);
		Assert.Equal(2, first.Statistics.NumberOfTransactionsStatements);
		foreach (var statement in first.StatementsModel.Statements)
		{
			Assert.True(
				statement.Alerts.Any(alert => alert.HelpTopic == "CrossThreadSessionUsage"));
		}
	}
}

And for additional fun, here is the code to implement the feature:

public class CrossThreadSessionUsage : AbstractStatementProcessor
{
	public override void AfterAttachingToSession(SessionInformation session, TransactionStatement transaction)
	{
		AfterAttachingToSession(session, (SqlStatement)transaction);
	}

	public override void AfterAttachingToSession(SessionInformation sessionInformation, SqlStatement statement)
	{
		if (sessionInformation.SessionId.IdentifierId.ThreadId ==
			statement.SessionId.IdentifierId.ThreadId)
			return;
		statement.AcceptAlert(AlertInformation.CrossThreadSessionUsage());
	}
}

I did have to change some of the innards so NH Prof will track both the session id and the thread id, but that was quite easy to do and the only thing that actually took any time at all.

time to read 2 min | 367 words

I was reading Jamie Fraser’s blog when I run into this post. In the post, Jamie talks about how he want to make it to fake data that the user is able to print from a site.

The example given is a payslip, which we don’t want the user to be able to successfully change. The solution that Jamie came up with is to watermark the image. His example is:

Unmodified Watermarked

But what aroused my curiosity is:

The one issue I've encountered however is that it is simply not possible to completely prevent editing of the files - a skilled Photoshop user could work around pretty much any watermark, and of course detecting tampering is quite difficult for the casual viewer

Well, that is true enough, but you don’t have to do it this way. Instead of thinking in terms of making it hard to the user to fake the data, sign it.

You can just do this:

image

The numbers at the bottom compromise a cryptographically meaningful signing of the data. So without knowing your private key, no one can actually fake the data, no matter how good their photoshopping skills are. Now, you may want to go with the watermarking anyway, to make it harder for the casual user to do so, and because even with signing, how many people are going to actually check the signature?

But if you need to take it to court, or something similar, proving that this is a fake or not would be a very easy task.

OR/M suitability

time to read 2 min | 227 words

A few days ago, I run into this tweet:

image

My answer to that is composed of two parts.

People usually think that I am being facetious when they ask me when they should use NHibernate, and I answer: “Whenever you are using a relational database”. I am not, I am quite serious in that regard. Well, there is a small subtext here in which I assume that you are talking about OLTP rather than reporting or other BI activities.

The reason for that is quite simple, NHibernate (and other OR/Ms, I guess) is doing a lot to make working with RDMBS easy. To try to assume that you can do better than that is… quite a challenge, shall we say? I have seen quite a few people try, and I have seen very few get something reasonable working. I have seen no one that has been served well by that decision when you sit down to make the ROI.

Now, the second part of the answer is that I am not sure that Twitter, as I would design it, would make much use of a relational database. Twitter seems to be ideally suited for a hierarchical database, rather than a relational one.

time to read 1 min | 155 words

I spent the last few days writing the NHibernate in Desktop Apps sample. Since I didn’t feel like doing something adventurous, I choose to use the age old ToDo app as the sample.

Now that I have finished it, I run some stats on it, and it is… interesting.

Here is the number of lines split into infrastructure and application code:

image

The funny part about this is that this is for an application that has three forms altogether and very little behavior.

The not so funny part is that I fully expect that extending the application would require very few modifications to infrastructure code, while the support of the infrastructure means that I can churning out new features without really having to think about anything but that specific feature.

time to read 3 min | 417 words

image As usual, reading Udi’s articles is an interesting experience, and his latest one, Employing the Domain Model Pattern is no exception.

I am actually a proponent about thinking twice before approaching a domain model architecture, but not because I see it as a way to manage change. I see it as a way to manage complexity, and you need a fairly high threshold of complexity before the domain model pattern starts to justify itself. And I enthusiastically agree about the domain events model.

But probably the most important topic raised in the article is that when you sit down to think about your domain model, the last thing you should do is start drawing an Entity Relationship Diagram.

As a matter of fact, I would go a step further and say that if you are starting with the ERD, or even if you just think about your domain model mainly in terms of ERD, then you are working with an anemic domain model.

Now, take heart, as Udi mentioned, not every persistent object model is a domain model. I don’t have a problem with people mapping their persistence model using an ERD, for that matter, that is what it is for.

The problem starts when you try to use this as a domain model. And a domain model’s chief reason for existence is to incorporate both behavior and data. And you can’t do behaviors with ERD. You usually won’t notice that until it is too late, for that matter.

There are different ways to approach building different types of models. A persistence model vs. a domain model vs. transport model. All of them have their own requirements and needs. And while it is often possible to combine those needs into a single model when those needs are small, as the application grows larger, things are going to start creaking.

At that point, you’ll find that more and more you are going to put behaviors outside of the model, because it is too painful to add additional behavior inside.

This is part of the reason why I like the idea of domain events, the handlers for the domain events are part of the domain, since they form what is sure to be the most interesting (from business perspective) layer of the application.

FUTURE POSTS

  1. Semantic image search in RavenDB - about one day 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   ... ...
}