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,640
|
Comments: 51,255
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 316 words

Okay, here is something that I had to deal with today. I had to implement the dated-rev-report command in SvnBridge. This command sends a date to the server, and get the first revision id that was committed before to that date. Because code is unambiguous, if we were using SQL, it would have been:

CREATE PROC DatedRevReport 
	@requestedDate DATETIME
AS
	SELECT TOP 1 RevisionId
	FROM Revisions
	WHERE CommittedDate < @requestedDate
	ORDER BY CommittedDate DESC

Simple, right? Except that the interface that I have to TFS is not SQL (and I would be pretty sad if it was, so that is a good thing). I have to go through the TFS API in order to get that result.

Here is the API that I have to work with (actually, that is a drastically simplified API, but it contains all the stuff required to solve this issue).

public interface ISourceControl
{
	int GetLatestId();
	LogItem QueryLog(VersionSpec from, VersionSpec to, int countToReturn);
}

public class LogItem
{
	public SourceItemHistory[] History;
}

public class History
{
	public int ChangeSetId;
	public DateTime CommitDateTime;
}

public class DateVersionSpec : VersionSpec
{
	public DateTime Date;
}

public class ChangesetVersionSpec : VersionSpec
{
	public int ChangesetId;
}

Your task, if you agree to accept it, is to build implement the following method:

public int GetVersionForDate(DateTime date)
{
	// your implementation here
}

One important consideration is that you should reduce remote calls. I managed to get it down to 4 remote calls for the worst case scenario. It could have been 3, but TFS has some... finicky date handling.

So, how would you solve the issue?

time to read 4 min | 788 words

A while ago Udi talked about How to create fully encapsulated Domain Models. He gave a great example, but more importantly, he gave some general rules of the thumb about how to create such a system.

Those rules are, if I understand them correctly:

  • Every message should resolve to a single method call on a domain object. The message handler is responsible for setting up the environment to call this method (getting the parameters, mostly).
  • The domain model should not throw exceptions. This is mostly because attempting to handle exceptions often lead to handling too much or too little. It is easier to define all the domain operations as throwing no exceptions, in which case all exceptions are infrastructure exceptions (or bugs).
  • Communication to the outside world is done using events. To decouple the domain from the service layer.

Things that I am not sure about:

  • What are the roles of services using this model. As a simple example, when new user is created, we should send a welcome email. This involves technical services (IEmailSender, ITemplateEngine, etc) and probably a domain service as well (INotifications.SendWelcome) I am not sure where those fit in.
  • Rules - Same thing. How do I handle things like executing a set of rules in a business action?

Anyway, I thought that it would be interesting to see how I would approach Udi's sample using my own style. What I ended up with is this:

public class AddGameToCartMessageHandler : BaseMessageHandler<AddGameToCartMessage>
{
    IRepository<TradeInCart> tradesRepository;
    IRepository<Game> gamesRepository;

    public AddGameToCartMessageHandler(
        IRepository<TradeInCart> tradesRepository,
        IRepository<Game> gamesRepository)
    {
        this.tradesRepository = tradesRepository;
        this.gamesRepository = gamesRepository;
    }

    [Transaction]
    public override void Handle(AddGameToCartMessage m)
    {
        Future<TradeInCart> cart = tradesRepository.GetFuture<TradeInCart>(m.CartId); 
        Future<TradeInCart> g = gamesRepository.GetFuture<Game>(m.GameId);

        SetupErrorHandling();

        cart.Value.Add(g.Value);
    }

    private void SetupErrorHandling()
    {
        Domain.FailureEvents.GameReportedLost = delegate
        {
             Bus.Return((int) ErrorCodes.GameReportedLost);
        };     
        Domain.FailureEvents.CartIsFull = delegate
        {
            Bus.Return((int) ErrorCodes.CartIsFull);
        };

        Domain.FailureEvents.MaxNumberOfSameGamePerCartReached = delegate
        {
            Bus.Return((int) ErrorCodes.MaxNumberOfSameGamePerCartReached);
        };
    }
}

It doesn't look that different, but let us look at the details, shall we?

  • We don't deal with the session. That is duplicate code that can get quite annoying.
  • Transactions are implicit. This saves the whole (who forgot to call tx.Commit() ) again.
  • The use of futures to get both cart and game at the cost of a single call to the DB.
  • Moved error handling to a separate method.
  • We do not use events, this saves us the trouble of having to unregister them (or manage them using weak references)
  • What we can't see is that an attempt from the domain model to call a delegate that wasn't registered would raise an error. I don't believe in ignoring errors.

I am not sure what to do about the transaction when we run into a domain error. Should we assume that the domain is smart enough to revert state changes? I am pretty sure that this is not something that we would like to assume. But, does it make sense to rollback the transaction?  An attempt to add a game that was report lost should probably trigger some alert somewhere, we don't want to roll that back, obviously.

Thoughts?

time to read 4 min | 624 words

Okay, NServiceBus Distributor deserve its own post. Broadly, the way it works is fairly simple.

Here is a simplified diagram, showing the workers and their queues, as well as the distributor and its queue. In here they are shown running on separate machines, but they could also be on the different processes.

image

Now, let us zoom into the distributor a bit, shall we?

image

Hm, we actually have two queues for the distributor, one is for workers, reporting for work (on the left), the second is applicative messages, which needs to be processed.

The reason that I think this is beautiful is quite simple, you submit work to the distributor queue, which forward it to one of the workers. So far, pretty standard stuff. The fun part starts when you talk about managing the workers.

On startup, each of the workers will send T notifications to the distributor, where T is the number of threads it is configured to use (yes, workers are threads in a machine, not a machine). When the distributor send a message to a worker, it also take it out from the available list. When the worker is done, it tells the distributor that it is ready again, at which point it become available to more work.

Very elegant solution. It is even more elegant when you look at the code to handle that:

private void messageBusTransport_TransportMessageReceived(
        object sender,
        TransportMessageReceivedEventArgs e)
{
    if (disabled)
        this.Rollback();

    string destination = this.workerManager.PopAvailableWorker();

    if (destination == null)
        this.Rollback();
    else
    {
        logger.Debug("Sending message to: " + destination);
        this.messageBusTransport.Send(e.Message, destination);
    }
}

Notice what happens if we don't have an available worker. We simply rollback our current action and move on. We will try again in a short while, and hopefully then we will have a worker to dispatch to.

What about failure scenarios?

Well, at most a worker can "lose" a single message, since if it crashed, it will not report itself as available. If a machine crashes, then we might lose a bunch of messages (all the messages currently worked on by the workers on that machine), but it doesn't hurt the overall system stability. When that machine comes back online, it will immediately starts to process those messages again.

Hm, there is actually an issue here with this scenario, since the workers will start working on their existing messages, but at the same time will report that they are ready for work. This just means that they will have work already queued by the time they are finished (and then they would report they are available again, of course). In general, I am okay with that.

What about the distributor itself? Again, crashing the distributor is generally not an issue. We are talking about using a durable transport here, so unprocessed messages will be saved and received when the distributor comes back again.

At the moment, I am not sure what happens if the distributor goes down for a lengthy period of time.

time to read 6 min | 1190 words

I have been planning to check this out for a while now, but I seem to never get the time. Today I made time for this. As usual in such cases, this post is a stream of consciousness. You get my thoughts as I am thinking them.

Before trying to understand anything about NServiceBus, you probably need to understand a bit about distributed systems and messaging. NServiceBus is structured around a bus (into which you can put messages) and message handlers (which handles messages for you). On top of this very simple idea, everything else is built. This forces you to think in a way that makes a lot of sense in distributed, high scalability, scenarios. I got a lot of the concepts behind NServiceBus because I read Programming Erlang, in which the same concepts are explained beautifully.

Just to note, I am probably not going to make a lot of sense to people who are trying to understand NServiceBus. I am going to go over the code here. Which is how I learn new stuff.

Let us get to the review. The first thing that I noticed was this:

image

AllProjects is really all projects. That include samples, tests, extras, etc.

Looking into the NServiceBus project itself made me much calmer, I can handle this:

image 

In fact, most of the projects contains very few files (one or two in many cases). This is probably done to allow you to pick & choose your dependencies, without having to deal with unrelated stuff.

BaseMessageHandler is a simple base class that simply define the Bus property.

This, however, is annoying.

image

I don't like to have camelCase exposed in my classes. Yes, it is just an issue of style, I know... The bracing styles in NServiceBus has a strange feel to it, but I have R#, and it can fix that ;-)

This is where the fun really starts:

image

Publish and Subscribe looks remarkably like their equivalent in Retlang. Same model, after all.

I am not really sure about the difference between Publish and Send yet. And SendLocal doesn't really make any sort of sense yet.

I am not happy with Return(errorCode) either. I don't like using codes for errors, it reminds me when I had to interface to a mainframe, and 12 was corrupted file and 14 corrupted header, etc. Reading further into the code reveals that typical usage of this is with enum

HandleCurrentMessageLater is interesting, and I have seen some samples on Udi's blog on where it is used (handle the message after another transaction has finished running). Not sure what DoNotContinueDispatchingCurrentMessageToHandlers purpose is yet.

ICallback interface is interesting:

image

Need to check it out in more depth, when I figure it what you are registering for and the usage for that.

IMessage is a marker interface, nothing more.

There are a couple of interesting attributes as well:

  • Recoverable - this is a durable message, and it should survive transient failures en route.
  • TimeToBeReceived - what is the lifetime of this message. I am not really sure that this is a good way to specify this. I would assume that things like that are much more dynamic than the code. As a simple example, a burst scenario may cause high latency for processing work. I have a post dedicated to this issue here.

ReadyMessage (on the Messages.cs file) is interesting. I followed the references, but I don't think that I understand what is going on when it is handled.

Moving on, NServiceBus.Saga:

image

A saga is a way to handle a series of messages that are related to one another.

image

A good example may be submitting a order. It needs a manager authorization before it can be done. So you send a message for it to be approved, and you will only continue processing the order after you got the authorization message. Udi has a sample here.

The reason for the large numbers of projects, and the reason many of them contains only a single class or two becomes clear when you track down the classes that implements this bit:

image

I don't like either of the two implementers that are provided (not my style, basically), but it is going to be trivial to supply a new implementation that I would be happy with. I really like that ability. For that matter, the Persister.Deserialize() method is really fun to read. Really cool way to solve the problem.

Overall, I like the idea of Saga very much. It seems to me like there aren't really better alternative to Erlang's recieve keyword in C#.

Speaking of replacing the building blocks, NServiceBus use the following interface to abstract the container. You can usually guess what is the inspiration for the container abstraction. In this case, this is Spring.

image

For using Windsor, we would need to write a simple adapter. (Basically mapping Build() calls to Resolve() calls).

The only really interesting bit is with BuildAndDispatch. This is how NServiceBus deals with making calls to generic interfaces without knowing up front what the generic parameter would be. I don't like it, but I don't see any other choice.

NServiceBus.Testing.

image

Not much to say about it, except that it is a great example of how much of a difference building an explicit interface for testing can make.

TimeoutMessageHandler made my head hurt. Go on, take a look. Now figure out what it does... The code is deceptively simple, because you have to think in terms of reentrancy.

I figured out what the ICallback is for, it is the result of the Send()

bus.Send(command).Register(cb, extraData);

Okay, that just about finishes with the core services that NServiceBus has to offer. Next, the infrastructure components are Transport and Bus, there is also the concept of a distributor, but I am not sure what this is, looks like the manager in a grid.

Transport is how NServiceBus abstract the details of the network communication.

Bus manages the messages, correlation, translation between transport messages and application message, dispatching to message handlers, etc.

There is also subscription manager and subscription storage, which I understand conceptually, but not in detail.

The distributor section of NServiceBus is a thing of beauty. Which I'll describe in the next post.

time to read 3 min | 456 words

I am reading NServiceBus' code at the moment, and I run into this idea:

[Serializable]
[Recoverable]
[TimeToBeReceived(“0:01:00.000")]
public class ScheduleInterviewMessage : IMessage
{
    public Guid InterviewerId;
    public Guid CandidateId;
    public DateTime RequestedTime;
}

I don't like hard coding this value in the message. Obviously this is something that is tied very closed to the idea of the message. Time to live is certainly something that I would want to closely tie to the message itself. But hard coding the value goes against a lot of instincts.

A while ago I faced a similar issue, in that case, it was scheduling tasks. The timing of the task was tied to what it did. The last example that I had on that post is this:

[Occurances(OccureEvery.Day, At = "08:00", RunAtHolidays = false)]
public class SendSmsTwoDaysBeforeEventStart : ScheduledTask

Notice the At = "08:00" ? It bothered me for a while, until I came to the conclusion that I was embedding the wrong piece of information in the code.

I didn't want this to run at 08:00, I want it to run in the morning. 08:00 was just a handy designation for that. That thought was quickly followed by:

public enum ScheduledTimes
{
     Midnight,
     EarlyMorning,
     Morning,
     Noon,
     Afternoon,
     Evening    
}

And the code turned to:

[Occurances(OccureEvery.Day, At = ScheduledTimes.Morning, RunAtHolidays = false)]
public class SendSmsTwoDaysBeforeEventStart : ScheduledTask

The difference here is that I no longer hard code a specific value, I put the idea there. During deployment, I could have modified what morning meant, very easily.

Using the same approach, I would define something like:

public enum TimeToLive
{
    Immediate,
    Short,
    Medium,
    Long,
    Forever
}

I would probably allow to configure the time that each of those values map to, as well.

This allows to do things like update them on the fly (imagine having to survive a burst of traffic that slows the entire system), so you can increase the time to process a message without losing it.

time to read 5 min | 875 words

Recently I had a number of conversations about how to create a maintainable environment, not only for advanced developers, but an environment that enables beginners and intermediate developers to create good, maintainable, scalable solutions.

This problem is not a simple one, and there aren't really one off solutions. However, there is quite a lot that can be done, and I am very disturbed by the assumption that nothing can be done about it.

I noticed that a major part of the problem seems to be in the underlying assumption that in order to make it possible for beginners/intermediate developers to work with the application, you have to do one of two things. Embark on a long education period or dumb down the application to a level that beginners can deal with.

I am using the term "dumb down" on purpose. This approach goes for the easiest solution possible, those solutions tend to be very easy and supportive for trivial scenarios, but they get very complicate for any real world scenario. They also tend to be focused on RAD, with little regard to the overall maintainability of the solution. I am pretty sure that you have encounter such systems before, they are depressingly common.

The end result of choosing such an approach is an application whose complexity is not handled by the underlying platform, but rather at each individual case. This significantly complicate the applicatIon and working with in over time. As a quick example (which is sure to annoy a lot of people), I consider any application that has "new SqlConnection()" in it outside the infrastructure layer to be such a system.

The other alternative, however, is a lengthy training cycle, and slower productivity all around until you get to be proficient in the new approach. And, of course, some people will have really hard time adjusting.

Or so many people believe, at least. I strongly disagree with the previous statement.

The way I would choose for such a scenario (a team composed of developers of varying skills, being non trivial application) is to accept the fact that you cannot escape from the complexity and embrace that fact. Instead of trying to base the application on an overly simple foundation, I would base it on advance platform.

This advance platform would be able to scale to handle the complexity of the application, while concentrating that complexity into the infrastructure layer.

Some of the concepts involved in creating such an architecture are:

  • Infrastructure Ignorance - If I have to deal with my infrastructure explicitly, then I need to have developers dealing with it on a regular basis. That doesn't mesh well with the idea of moving all the complexity to the infrastructure.
  • Fizz Buzz concepts - the code that a developer should write should be simple and easy to follow.
  • Follow good design principals - the code written should naturally lean toward single responsibility principal, separation of concerns, etc
  • Easy to figure out - It should be simpler than the alternative for any non trivial scenario. Ideally, you can explain how to solve most scenarios using this approach in half an hour or less (ignoring the infrastructure part, which may be very complex).
  • No training wheels - one of the things that drives me crazy is having two ways to do things. One for the average developer, the second for the architect. This usually comes out of putting training wheels on the first approach that make it hard to deal with in more advance scenarios. I see this as a sign of contempt for the rest of the members of the team. If you expect the rest of the team to work in a certain way, make damn sure that this is a way that this is a way that you can live with.

I think that I manage to get fairly close to this in my previous project, and it has proven to be a successful one. I talk about it a bit in this post.

I based that system on IoC, NHibernate and WCF. None of this concepts was exposed to the other developers. In fact, after setting this up, we were able to focus on the actual business issues far more often than on the technology involved.

By the way, I would fully expect that during the project, significant attempts would be made to get the other developers to understand. This technique is about getting a project started and the team productive very early, and doing this using a stable foundation.

Now, what is this anti corruption stuff in the title of this post? This is very simple, actually. It is here as more than the anti corruption than the anti corruption layers that Feathers is talking about in Working Effectively With Legacy Code. In this case, we start with the assumption that the infrastructure that we will use (even if we are the one building it) is suspect and should not be trusted, so we will do everything in our power to isolate our code from the infrastructure.

An important benefit of this approach is that we get the ability to modify the infrastructure independently of our application. This means that we can make significant changes very easily, because there is little to no dependencies between the two.

time to read 2 min | 322 words

A couple of days ago my MacBook Pro has arrived. I didn't have much chance to play with it until today, but right now I am trying to see how compatible we really are. I haven't really ever used a Mac (short demo sessions on other people's doesn't count) so it is an interesting experience.

I can tell you right now that my biggest worry, the keyboard layout / shortcuts, is probably going to be fine, since I seem to be getting the hang of it without too much problem.

However, I am literally a newbie at this, and it is very hard to get back to this stage. I am going to detail some of the stuff that I run into, hopefully I'll get some more information as I go along.

Safari - It kills me how it and Gmail interacts. To be rather exact, it kills me that it doesn't consider buttons to be a valid target for <Tab>. I'll probably try FireFox, but I want to try it out first.

  • I am writing this in Etco, and it seems like a reasonable application, very comparable to Live Writer, although with a completely different UI.
  • It took me a long time to figure out Command+Tab vs. Command + `, and it doesn't help that it seems like all the Mac application open new windows like mad.
  • Close window vs. Close Application - that is strange.
  • Getting used to Command, Option, Ctrl, Alt - Oh my God, that is too much.
  • There are not context menus that I could find. It took forever to find out how you can do spell checking.
  • Can't find a way to use the keyboard to access the application menu (Alt+F, in Windows).

Overall, I finding that it is obvious that I can like it, but the start seems to be tough. Just the scroll by moving two fingers is a delight.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

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