Saturday, December 23, 2006

So I'm coming down to a real beta1 release. I've been polishing things up and trying to get some bug fixes for everything I can find and stream line the example web site for demo purposes. I even cooked up some graphics and a logo! Check this out:

So I'm planning on using this as the new logo for now, I like the pleasantly corny one liner "Now we're NBusiness". I am no artist by any stretch but I'm reasonably happy with it so far I'm thinking that the N should maybe be twisted just a little so that it appears to be printed on the briefcase rather than floating on it... but i don't have the tools or the skillz to do that. If anyone thought that they might want to try it out let me know and I can email you the layers (you can also get them out of the source code at Code Plex).

I'll probably release the beta on tuesday, after christmas to help maximize exposure on codeplex... but then again maybe no one else would be releasing for the next couple days and it would remain on the newly released list longer. But if no one is even looking... hmm.

So I had a realy interesting problem spring up the other day that turned out to be pretty tricky to solve. I haven't had a fresh computer science problem in a while! It turns out that when you have even a moderately complex object graph it is pretty easy to end up in a never ending loop during persistence. Meaning if you call Save() on a particular entity it will then save all of its parents, itself then all of its children. Which is what you want really but then the children try to save their parents and parents their children etc. So you can end up going round and round forever if your ancestors share a common parent with you. I'll show a diagram of the DB scheme from the Example website to illustrate what I'm talking about.

So you can see there if you're saving a Company entity it circles back around to it's parent Address and you get stuck in an infinite loop.

So to resolve this I had some ideas where I tried to add check to not update something twice (which is good still) but the problem was with an entity needing to also persist its relationships and the loop would never be solved or we'd end up with only a partial (and unpredictable) persist of the object graph. So I thought about it pretty hard and came up with what I think is the solution.

So the idea is basically like a depth first search. Only since we're using the metaphor of parent/child/sibling its more like a height first search. The problem is that this isn't exatly a strict tree, the relationships are seemingly random and branches can go from any node to any other node however two nodes cannot be parents of each other or children of each other. Furthermore, you cannot make any assumptions about which node begins the persist! So the rules I came up with are pretty simple:

  1. Always persist upwards first.
  2. Persist yourself.
  3. If being persisted from above the persist downwards.

That's it essentially. So what happens is that the first nod persists its parents then they persist their parents etc. all the way to the top. Then since they were persisted from below and not from above they do not cascade persists downwards. It will wind back down to the original node then begin going downwards. Each downward node will persist all parents and then go further down the tree.

In this scenario you may have some nodes that will not get persisted (children of parents who do not have any other relations with the original persister), however this is predictable. Meaning, that when you do a persist you can readily know ahead of time what will not get persisted due to the relationships then call a persist on the other entities as needed. So I went from an endless loop to persisting 1720 entities in about .3 seconds by implementing those rules. So that made me happy.

Though now that I think more about it I'm not sure I handled it correctly for the sibling relationship scenario. It should be possible I just don't think I hooked it up yet. I'll take a look at it tonight.


Post a Comment

Links to this post:

Create a Link

<< Home