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,276
Privacy Policy · Terms
filter by tags archive
time to read 3 min | 552 words

Tomer Gabel had a problem with raising events from outside the class that declared them. The problem was compounded by the need to process the event asynchoronously, since System.Delegate doesn't implement BeginInvoke().

His solution was to use Reflection to do that. I was interested enough to investigate whatever I could do that without Reflection. I was surprised to learn that BeginInvoke was only available on specialized delegates. My solution is based around this article: Calling Synchronous Methods Asynchronously which truly proves that you can solve anything in computers by putting another layer of indirection, except too many layers of indirection :-)

Since Tomer seems to want a contain to hold many events, I decided that I would skip events and go straight to the source, delegates. The container class that I've here has a list of registered events and list of subscribers. Subscribing to a non-existing method creates it. Firing events can be done in three modes:

  • Totally synchoronously, which means that you wait until all the subscribers have finished.
  • Asynchoronously firing the event, but each subscriber is processed in turn.
  • Asynchoronously firing the event, each subscriber is proccessed asynchoronously.

Note: Exceptions during calls is a tricky subject, I tried to give as much information as possible, but I've no idea how to get an exception thrown from async method.

There is no reflection there, but a lot of indirection, the whole thing is based around the concept that while you may not be able to run a Delegate asyncrously, you can run a method asyncrously that would run the delegate. If you managed to follow the last sentence, I applaud you.

private delegate void DynamicInvoke(Delegate d, object[] args);

public
 void BeginDynamicInvoke(Delegate call, object[] args, EventHandler callback)
{
 this.fireSignle = new DynamicInvoke(CallDynamicInvoke);
 this.fireSignle.BeginInvoke(call, args, new AsyncCallback(AsyncCallback), null);
}

private
 void CallDynamicInvoke(Delegate d, object[] args)
{
 d.DynamicInvoke(args);
}

It's too big to post fully on the blog, you can find it here.

Unsubscribing and deleting events are left as an exercise to the reader :-)

time to read 1 min | 164 words

Joel has a very interesting article about the reasoning behind spam blogs. As always, it's money that is the cause, but this time the "victim" is Google. And that gives me some hope that it will stop.

A spam blog is usually just an aggeration of links from other sites which usually has a Google AdSense account. Then a zombie network is used to click on the links, and the spammers colleccts the profits. The interesting thing here is that Google is both the target and the supplier here, since BlogSpot, which it own, is one of the bigger targets for scripted-blog-generation. Google is losing money because of this, and that gives them a pretty strong incentive to stop that. Further more, they are losing the trust of the advertisiers. If I know that paying for AdSense would get me 50% visits from some spammer, I'm really going to consider whatever to pay for that or not...

time to read 2 min | 267 words

I've had a fairly strong negative reaction to #Develop in the past, mostly because you really couldn't use if without the IDE started to throw exceptions and refusing to work (my pet peeve was the inability to create & rename new folders, an issue that often require a manual editing of the project file.)

I got a couple of recommendation about #Develop 2, which is currently only available from the Subversion repository (svn://sharpdevelop.net/corsavy/trunk) (or so I understand). I'm writing this review based on revision 619.

Over all, I've got a good feeling about it. The interface is much more proffesional, and it has a built in Boo.

Some things that I didn't like:

  • Over eager highlighting and intellisense. It should give me a couple hundred milli seconds of wait before doing that, moving the cursor over the code is like watching fireworks :-)
  • Search & Replace has improved tremendously, but I couldn't figure out how to do S&R using regular expressiong with replacing tagged text. In VS.Net, I can use:
    seach text: url = {"[^"]+"}
    replace with: DoGet(\1)
    And it would replace url = "something" to DoGet("something")

The #Develop team has a blog here.

time to read 1 min | 170 words

Does anyone knows of a C# 2.0 code formatter that is available now? I want something just like what ReSharper has for 1.1, where you get tons of options for just about anything.

Spesifically, I need something that will understand how to handle anonymous delegates. Right now R# doesn't handle them very well. My current code style is:

//one liner
sw.Action = delegate(ISalesContext sales) { return sales.Items.Count;}

//multi line

sw.Action = delegate(ISalesContext sales)
{
    if(sales.Date.AddMonths(1) > DateTime.Month)
        return 0;
    return sales.Items.Count;
}
time to read 1 min | 143 words

Charles Petzold has a really good talk here about the problems that VS.Net gets you with being too smart. Best quote:

IntelliSense is considered by some to be the most important programming innovation since caffeine

I tend to agree with him, although I come to it from a different angle. From a non UI perspective, I find that people often takes the easy path that they saw on the demos, and very quickly ends up with unmaintainable mess. I'm a big believer in making the computer work for me, but I like to do it using abstractions and code, not via wizard magic.

time to read 2 min | 267 words

There is a message in Boo about the problem of allowing assignment in conditinals:

if a = b:
   doSomething()

I liked the way Christoph pharsed the issue: Now even if you don't notice this yourself, at least the compiler will warn you, thus saving you from hours of tedious debugging. (Ok, maybe I am exaggerating, but let's assume the worst case.)

One thing that I noticed that when I'm developing, most of the time is not dedicated to design or writing code, it's dedicated to those little problems that I run into. For instance, I mistakenly defined a one to many relationship as a serialaziable relationship (meaning that the class is serialized to a BLOB in the DB). I wasted hours on that thing, until I finally looked at what was happening and it hit me. Another thing was the associtaions, which took a while to resolve.

Right now I wasted a lot of time on trying to get Subverion merging to work. There is a lot of documentation about it, but I do it for the first time, so it's a "learning experiance"*. How much time do you find yourself dedicate to those side-tracks, those implementation details? Any suggestions on how to reduce this?

* Nice figure of speach to banging my head on the wall :-)

time to read 2 min | 263 words

A few days ago I asked why you can't treat IList<String> as IList<Object>, Wesner Moise commented with the explanation, and Mitch Denny has a post with a fuller explanation. One interesting thing that came up via a comment from Tomer Gabel was that the following code is legal:

static void Main(string[] args)
{
 object[] array = GetList();
 array[2] = 1;
}
public static object[] GetList()
{
 return new string[10];
}

 This suffer from exactly the same problem that you get with generics. In fact, while the code compiles, trying to run it results in ArrayTypeMismatchException. I never dug deep enough into the runtime so I could tell you how arrays are implemented, but I think that they are just getting special threatment from the runtime. Any Rotor hackers out there that can comment on that?

time to read 9 min | 1625 words

Like I said, I've just wrote a rule that used pretty much all the new features that C# 2 has to offer. I'm aware that I tend to like new things for their own sake, but I like to think that I'm using them wisely. Let's take an example, since this is the best way to do it, in my opinion. I present here a case similar to the one I ended up with, and I would appreciate comments about the readability / maintainability of the code.

I have a graph of objects, and I need to run various rules against it. Traversing the graph is trivial, but I usually need to do it while taking all sorts of things into account. In this case, I basically need to compare the two, and generate notifications (using yield return) based on what is going on there. Let's see an example, and then I could talk and be pretty sure that you understand what I'm talking about.

First, let's take a relatively simple scenario that bring this and several other concepts that I've talked about earlier. The scenario is simple, we have a context under which we operate, and we need to apply similar rules to different contexts. Most of the rules operate on time, for example: A store must sell at least 50 items a day.

It's a simple rule, isn't it? But the stores doesn't hold the data in a daily format, they hold a list of sales, and each sale has its associated date. The sales are already sorted by date, so it's should be very easy to do it, right? Well, it is, if you don't have a day without any sales. Does it trigger the rule? That depends, if it's a day that the store was closed, it wouldn't, but if it was opened and didn't sell a thing, there is probably something there that needs more attention. What happens if you want to run the rule with a granularity of a week? A month? A quarter? What happen if the rule has a granularity of a month but the data we has is only for a week. This get messy very fast.

At the end I decided that I would create a class that would encapsulate all those decisions, and that class would use the context to get the various options it needed (for instance, when the store is closed). Here is what I ended up with. Pay attention to GetItemsOnSameDay() and GetItemsOnSameWeek(), that is where the crux is happening.

public class StoreWalker
{
 Context context;
 Convertor<ISalesContext, int> action = DefaultAction;
 
 public StoreWalker(Context context)
 {
  this.context = context;
 }
 
 private int DefaultAction(ISalesContext salesContext)
 {
  return 1;
 }
 
 public Convertor<ISalesContext, int> Action
 {
  set 
  { 
   if (value==null)
    throw new ArgumentNullException("value");
   action = value;
  }
 }
 
 public int Walk(Store Store)
 {
  int count = 0;
  foreach(ISalesContext salesContext in GetItemsOnSameDay(Store))
  {
   count += action(salesContext);
  }
  return count;
 }
 
 public IEnumerable<ISalesContext> GetItemsOnSameDay(Store Store)
 {
  IList<Sale> items = new List<Sale>();
  DateTime currentDate = Context.Start;
  foreach(Sale item in Context.GetItems(Store))
  {
   while(currentDate != item.Date)
   {
    yield return new SalesContext(items, currentDate);
    items = newList<Sale>();
    currentDate = currentDate.AddDays(1);
   }
   items.Add(item);
  }
  while(currentDate != Context.End)
  {
   yield return new Store(items, currentDate);
   items = newList<Sale>();
   currentDate = currentDate.AddDays(1);
  }
 }
 
 public IEnumerable<ISalesContext> GetItemsOnSameWeek(Store Store)
 {
  IList<Sale> items = new List<Sale>();
  DateTime start = Context.Start;
  foreach(ISalesContext salesContext in GetItemsOnSameDay(Store))
  {
   items.AddRange(childStore.Items);
   if(salesContext.Date.DayOfWeek == DayOfWeek.Sunday)
   {
    yield return new SalesContext(items, start,  salesContext.Date);
    start =  salesContext;
    items = new List<Sale>();
   }
  }
 }
}

What GetItemsOnSameDay() does is to return provide a way to iterate over a store, and make sure that every day is accountable to. The GetItemsOnSameWeek() builts on GetItemsOnSameDay(). I can very easily add methods that would make the calculations for a month or a quarter, and they would be simple, since they wouldn't need to check for missing weeks or months.

The nice part about it is that the whole thing is lazily evaluated, so if you're running it on large amounts of data, there is no need to build the graph and then run on it, you run on the graph as you go along, and then the objects are GC'ed. However, I'm not sure what the implications of this are performance wise. There are some problems with recursive iterators that you should be concerned about if you're using it for large data sets. I don't think that this apply here, as it's not about blindly forwarding methods calls (as in the case of the recusrive iterators), but each iterator in this case does work on each own, and it make it conceptually much easier to understand the system.

The more esoteric stuff comes later, when you need to run the rules over a store. If I was using .Net 1.1 or Java, I would need to use the Template Method, and for each rule that I would need, I would have to create a sub-class of StoreWalker and put the things that I need to check there. I find it limiting because most of the time I only need a couple of lines to express the difference, and I only use it in one place. I choose to go with Generic Template Delegate.

How do we find out how much items was sold from the store?

public int GetNumberOfItemsSold()
{
 StoreWalker sw  = new StoreWalker(Context);
 sw.Action = delegate(ISalesContext salesContext) { return salesContext.Sales.Count; };
 return sw.Walk(Store);
}

How do we find the busiest day? This one uses local variables, so it can "remember" the current maximum is.

public DateTime GetBusiestDay()
{
  StoreWalker sw = new StoreWalker(Context);
  int max  = -1;
  ISalesContext maxSaleContext;
  sw.Action = delegate(ISalesContext salesContext) 
  {
    if(g.Children.Count>max)
    {
      max = salesContext.Sales.Count;
      maxSaleContext = salesContext;
    }
    return 1; 
 };
 sw.Walk(Store);
 return maxSaleContext == null ? DateTime.MinValue : maxSaleContext.Date;

Total number of sales?

public int GetNumberOfSales()
{
   return new StoreWalker(Context).Walk(Store);
}

I chatted with Oren Ellenbogen about this, and he claims that the maintainability of the code is compromised. The idea is that it would cost you five minutes to do it the old way (using Template Method), and then it's more maintainable. I argued that while this does require a shift in thinking, it pays off very shortly by using these type of techniques. I certainly don't advocate putting a large method inside an anonymous delegate, but even if it's a complex calculation that you want to do, you can still get the benefits of merely writing the method and then wiring to the walker's action.

Thoughts?

time to read 1 min | 181 words

VS 2005 has a great concept called snippets. It's a wonder it didn't have it before, since it's a very basic item, but at least we got it now. There is a community site where you can get snippets from the community.

All in all, I think that this is a laudable idea, but I find the implementation problematic.

Take a look at the site, it's a very clean UI, and you can see the last 5 entries. This is well and good, but I couldn't figure out how to get anything else. I consider myself pretty handy in computers, and this is just incomprehensible. Maybe they read Scoble's posts about search and took it too far?

I want a list of categories, or even a flat list. I want to browse the site, not search it. I would've been disappointed if they wouldn't have search, but having a search with magic pharses (see "recent 5" on the front page? "recent 50" doesn't work) is just useless.

time to read 3 min | 550 words

I just had a run into a mess of my own cooking. I had a set of classes, where one class held references to some other classes, and I didn’t map the associations properly. Not in the software and defiantly not in my mind.

Enter a lot of frustration about WTF is going on here.

I didn’t map all the associations and their cascades, which meant that I run into a lot of trouble when I started to really work with the model. Luckily I’ve a suite of tests that I can run, so I can play around with the cascades and see what is going on.

To add to the problem, I tried to do two things with it, the first was to follow the business logic and create associations that would make it easier to work with the objects. The second was to allow a to clear the database for the tests.

This got me into a lot of trouble…

I couldn’t use NHibernate to do it, because it failed to do a mass delete since the associations and cascades where in the way. At first I tried to work around that, but pretty soon it became clear that it’s not going to be possible.

I finally decided to separate the two concerns. I have not problem with having testing hooks, but changing the business logic because you want to have easier testing is a symptom that you went a long way too far.

I restored the association to the way they were supposed to be according to the model, and I’m going to keep an eye on that, I didn’t really paid attention to that before, and it’s going to be critical in a few days, when I start to put it all together.

For the tests, I’m using a simple function that deletes all the rows from the database after each test. On the first time that the tests are run, the whole database is recreated from scratch.

I’m not using Active Record to do it, since other tools need the schema as well, and I want to make sure that I don’t make accidental change to the schema by messing around with the business objects.

Still working on the rules, now it’s a rule that is a collection of rules. This one had me using just about any feature of C# 2 to get it done cleanly. I’ll post about it later.

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   ... ...