Ayende @ Rahien

Oren Eini aka Ayende Rahien CEO of Hibernating Rhinos LTD, which develops RavenDB, a NoSQL Open Source Document Database.

You can reach me by:

oren@ravendb.net

+972 52-548-6969

, @ Q j

Posts: 6,878 | Comments: 49,254

filter by tags archive
time to read 2 min | 222 words

I got the following bug report about NH Prof:

When renaming a session, the "enter" key seems to invoke the "Cancel" rather than the "Rename Session" button - this is slightly annoying (and unexpected) behavior.

image 

But that is impossible, here is the XAML for this:

image

And as it turned out, the code is correct, and the explanation for the error is wrong, but the behavior exists.

The actual problem turned out to be that if you hit enter while the focus is on the text box, the RenameSession method will be called, but the bound value will not be modified, since the default binding mode for text boxes is on focus lost. We can fix this using:

image 

Although this is logical, considering how WPF works, I still find it surprising, I would expect this to be a common scenario that would be handled OOTB.

time to read 3 min | 413 words

Continuing in my exploration of the Effectus code base, which originated from my Building a Desktop To-Do Application with NHibernate article on MSDN Magazine, I wanted to talk today about separating features into individual pieces in the application.

Each feature in the Effectus application is built as an isolated unit, that has little to do with any other features. This is very clear when you look at how they are organized:

image 

Sidenote: In each feature, the component parts are named the same (Presenter, View, Model). This is intentional, since it make it that much harder to mix stuff from other features.

Every feature has a pretty rigid structure, defined by the application, and trying to reuse stuff between features is frowned upon and avoided, even if doing so can reduce duplication. As a good example, the Model for both CreateNew and Edit features are identical, but they are two different classes with no attempt to merge it up.

The reason for this is quite simple, treating each feature as an isolated unit bring us great benefits, we can have different developers working on different features without the chance of stepping on each other toes, it is very hard for one feature to break another, deploying new features is easier to handle, etc. Trying to apply DRY and consolidate common pieces of code would introduce dependencies between features, and that is a bad idea.

But what about communication between features? What about when one feature needs to call another?

As it turned out, it is quite easy to turn a lot of the inter feature communication into an indirect calls, using pub/sub. We gain the independence from dependencies using pub/sub, while maintaining the feel of a well integrated product for the user. For the rare cases of one feature calling another, I create a simple Call(“FeatureName”) mechanism (in the code, this is Presenters.Show(name) method) that all us to just explicitly invoke another feature, maybe with some initial arguments. A more complete implementation will handle even that using pub/sub, probably with an integrator class that would dispatch the appropriate event to start and invoke the feature(s) that want to handle it.

You can read more about the architecture principles behind this system in: Application structure: Concepts & Features

time to read 4 min | 689 words

Continuing in my exploration of the Effectus code base, which originated from my Building a Desktop To-Do Application with NHibernate article on MSDN Magazine, I wanted to talk today about how to build an application infrastructure.

First, to be clear, I am not talking about infrastructure pieces such as caching, data access, etc. Those are generic concerns and you should be able to just get them from an off the shelve library. When I am talking about an application infrastructure, I am talking about the infrastructure code that you are going to need to write for a particular application. You are always going to have to do that, even if it is something as simple as just wiring the container together, or registering session handling, etc.

From my point of view, the point of the application infrastructure is to make writing the actual application features as simple as possible. Ideally, you want to make the infrastructure pieces handle everything that isn’t purely related to the feature you are implementing. The reason that an application infrastructure can do this while a generic infrastructure cannot is that an application infrastructure can make a lot of assumptions about the way the application is built.

Let us take the Main screen feature in Effectus, shall we, it will let us look at how this is implemented:

public Observable<int> CurrentPage { get; set; }


public
Fact CanMovePrev { get { return new Fact(CurrentPage, () => CurrentPage > 0); } } public Fact CanMoveNext { get { return new Fact(CurrentPage, () => CurrentPage + 1 < NumberOfPages); } } public void OnCreateNew() { Presenters.Show("CreateNew"); } public void OnActionsChoosen(ToDoAction action) { Presenters.Show("Edit", action.Id); } public void OnLoaded() { LoadPage(0); } public void OnMoveNext() { LoadPage(CurrentPage + 1); } public void OnMovePrev() { LoadPage(CurrentPage - 1); }

Looking the code, we can see that there are actually a lot of infrastructure playing a part here.

  • Automatic binding of On[Button Name]() methods to the button command.
    • Within this, enabling / disabling automatically using Can[Button Name] properties
  • Automatic binding of On[List name]Choosen(Item) to the selected item changed behavior on the list.
  • Automatic updates of property states using Fact.
  • Automatic updates of property values, using Observable.

There isn’t much to say about the automatic binding between UI actions and presenter methods, except that I think it is clear how this behavior reduce the level of infrastructure level code that you would have to write, test and maintain. But both Fact and Observable deserve a bit more explanation.

In the LoadPage() method, not shown here, we are updating the CurrentPage property, this will trigger invalidation of the all the facts bound to the value (CanMoveNext, CanMovePrev), which will force their re-evaluation. Since the infrastructure knows how to wire this up to the appropriate commands on the UI, this means that this will enable/disable the given controls automatically. What is more, look at the code. It is clear, concise and pretty easy to reason about and use.

I’ll leave the actual exploration of the implementation to you, it is fairly simple, but the idea is important. The Effectus application actually have more infrastructure code than it have code to implement its features. But that is a very small application. Just to give you an idea, the # of lines of code devoted to infrastructure in Effectus is about 600 LOC! In most applications, you probably wouldn’t even notice the amount of code that the infrastructure takes, but the effects are quite clear.

time to read 2 min | 357 words

I waited for a while after my article was posted, to see if anyone caught on to some of the things that I did in the sample code that weren’t related to NHibernate usage. It seems that no one caught on to that, so I’ll try pointing them out explicitly.

The basic format of a feature in Effectus is this:

image

Each feature have a Presenter (business logic for the feature), a View Model, which is directly bound to the View and is the main way that Presenter has to communicate with the View. The main responsibility of the Model is to be bound to the UI, and allow the presenter to update it, but it is not quite enough.

The UI also need to raise events and handle user input. A common example is handling button clicks. You can’t really map them into Model behavior, at least not easily and in a way that make sense to the developers. Instead, I defined a set of conventions. As you can see in the picture, based on the name of the element, we match is with the appropriate execute method and the way to decide if the command can execute. Under the cover, we generate the appropriate ICommand instance, bound to the Presenter behavior.

image

If you look at the code, you can see that the conventions extend even to handling the selected item changed in a list box, including passing the newly selected instance back to the presenter. Those conventions are project specific, based on what the project need, and they result in a code base that is very easy to read and follow. Moreover, they result in a codebase that is relatively free from infrastructure concerns.

I am going to have a few more posts about Effectus, can you figure out what else I put in that code base?

time to read 7 min | 1382 words

I have run into WPF memory leaks before, and I thought that I fixed them all, but I started getting more reports from people experiencing large memory usage from NH Prof. That lead me to try to track it down again.

Short story, you can get the reproduction here: http://github.com/ayende/wpf-mem-leak

I left an NH Prof instance running overnight, and was able to confirm that there is a memory leak in there, just by seeing how much more memory it had in task manager. One of the nicest things in Windows 7 is the ability to generate a dump directly from task manager.

I loaded that dump into windbg, loaded sos and mscrowks and set out to figure out what was taking so much memory. The most common way to start a memory leak issue is to start figuring out what is taking all this memory.  For that, the !dumpheap –stat command is great, since it give you memory usage by type and size. Here is what I found:

000007fee95b8a88   364674     11669568 MS.Utility.SingleItemList`1[[System.WeakReference, mscorlib]]
000007feeffe4748    51074     13161552 System.Object[]
000007fee77417a8   728189     17476536 MS.Internal.Data.ValueChangedEventArgs
000007fee95aafe8   364133     17478384 MS.Utility.ThreeItemList`1[[System.WeakReference, mscorlib]]
000007fee95b88c0   728814     17491536 MS.Utility.FrugalObjectList`1[[System.WeakReference, mscorlib]]
000007fee95b8838   728814     23322048 System.Windows.WeakEventManager+ListenerList
0000000000496170    19063     28004120      Free
000007fee7741730   728189     40778584 MS.Internal.Data.ValueChangedEventManager+ValueChangedRecord
000007fef0036c90   736210     47117440 System.EventHandler
000007feeffe7a90  1837702     58806464 System.WeakReference

I literally groaned when I saw that, based on my previous experience, it means that the memory leak is generated from inside WPF code, and that I am not likely to fix it. Then I set out to figure out where it is at. My suspicion fell on the statistics feature, it is the only thing that really updates frequently, after all.

So I setup to build a reproduction. Sadly, it is trivially easy to reproduce the issue. Given this XAML:

<StackPanel>
<ItemsControl ItemsSource="{Binding Path=Statistics}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Padding="2 0 0 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Key}"
ToolTip="{Binding Path=Key}"
TextTrimming="CharacterEllipsis" />
<GridSplitter Grid.Column="1"
Background="#3000"
Width="2"
Margin="2 0" />
<TextBlock Text="{Binding Path=Value}"
Grid.Column="2" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>

The following code will generate a memory leak:

public partial class Window1 : Window
{
readonly DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal)
{
Interval = TimeSpan.FromMilliseconds(1)
};

private readonly MyModel context;

public Window1()
{
InitializeComponent();
context = new MyModel();
context.UpdateData();
timer.Tick += (sender, args) => context.UpdateData();
DataContext = context;
timer.Start();
}

public class MyModel
{
public ObservableCollection<DictionaryEntry> Statistics { get; set; }

public MyModel()
{
Statistics = new ObservableCollection<DictionaryEntry>();
}

public void UpdateData()
{
Statistics.Clear();
Statistics.Add(new DictionaryEntry("Time", DateTime.Now.ToString()));
Statistics.Add(new DictionaryEntry("Mem", GC.GetTotalMemory(true).ToString("#,#")));
}
}
}

When you run the code, you can see that memory usage is going up all the time. As far as I can tell, I am not doing anything that is wrong or even slightly strange here. You can get the reproduction here: http://github.com/ayende/wpf-mem-leak

I tried several workarounds so far, but I didn’t like any of them. Any ideas?

time to read 7 min | 1378 words

One of the most annoying bug reports that we got for NH Prof is that it crash with out of memory exception after long use. We did the usual checkups, and the reason for the memory leak was obvious, something kept a lot of objects internal to WPF in memory. In fact, here are the heavy hitters, as extracted from the dump:

Count Size (kliobytes) Type
5,844 3,337 System.Byte[]
69,346 5,474 System.String
49,400 37,198 System.Object[]
1,524,355 47,636 MS.Utility.SingleItemList`1[[System.WeakReference,mscorlib]]
3,047,755 71,432 MS.Internal.Data.ValueChangedEventArgs
1,523,918 71,434 MS.Utility.ThreeItemList`1[[System.WeakReference,mscorlib]]
3,048,292 71,444 MS.Utility.FrugalObjectList`1[[System.WeakReference,mscorlib]]
3,048,292 95,259 System.Windows.WeakEventManager+ListenerList
3,047,755 166,674 MS.Internal.Data.ValueChangedEventManager+ValueChangedRecord
3,056,462 191,029 System.EventHandler
7,644,217 238,882 System.WeakReference

As you can see, this just says that we are doing something that cause WPF to keep a lot of data in memory. In fact, this looks like a classic case of “memory leak” in .NET, where we aren’t releasing references to something. This usually happen with events, and it was the first thing that I checked.

It took a while, but I convinced myself that this wasn’t that. The next step was to try to figure out what is causing this. I’ll skip the sordid tale for now, I’ll queue it up for posting at a later date. What we ended up with is a single line of code that we could prove caused the issue. If we removed it, there was no leak, if it was there, the leak appeared.

That was the point where I threw up my hands and asked Christopher to look at this, I couldn’t think of something bad that we were doing wrong, but Christopher and Rob are the experts in all things WPF.

Christopher managed to reproduce this in an isolated fashion. here is how it goes:

public class TestModel : INotifyPropertyChanged
{
private readonly DispatcherTimer timer;
private int count;

public event PropertyChangedEventHandler PropertyChanged = delegate { };

public TestModel()
{
timer = new DispatcherTimer(DispatcherPriority.Normal)
{
Interval = TimeSpan.FromMilliseconds(50)
};
timer.Tick += Timer_Tick;
timer.Start();
}

public IEnumerable Data
{
get
{
return new[]
{
new {Name = "Ayende"},
};
}
}

private void Timer_Tick(object sender, EventArgs e)
{
if (count++ % 100 == 0)
{
GC.Collect(2, GCCollectionMode.Forced);
Console.WriteLine("{0:#,#}", Process.GetCurrentProcess().WorkingSet64);
}
PropertyChanged(this, new PropertyChangedEventArgs("Data"));
}
}

This is a pretty standard model, showing data that updates frequently. (The short time on the time is to show the problem in a short amount of time.) Note that we are being explicit about forcing a GC release here, to make sure it isn’t just waste memory that haven’t been reclaimed yet.

And the XAML:

<Grid>
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>

Executing this will result in the following memory pattern:

image

Looking at the code, I really don’t see anything that is done wrong there.

I uploaded a sample project that demonstrate the issue here.

Am I going crazy? Am I being stupid? Or is select really broken?

time to read 1 min | 183 words

I got a few bug reports about NH Prof giving an error that looks somewhat like this one:

System.Windows.Markup.XamlParseException: Cannot convert string '0.5,1' in attribute 'EndPoint' to object of type 'System.Windows.Point'. Input string was not in a correct format. 

It took a while to figure out exactly what is going on, but I finally was able to track it down to this hotfix (note that this hotfix only take cares of list separator, while the problem exists for the decimal separator as well. Since I can’t really install the hotfix for all the users of NH Prof, I was left with having to work around that.

I whimpered a bit when I wrote this, but it works:

private static void EnsureThatTheCultureInfoIsValidForXamlParsing()
{
	var numberFormat = CultureInfo.CurrentCulture.NumberFormat;
	if (numberFormat.NumberDecimalSeparator == "." && 
		numberFormat.NumberGroupSeparator == ",") 
		return;
	Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
	Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
}

I wonder when I’ll get the bug report about NH Prof not respecting the user’s UI culture…

WPF is magic

time to read 1 min | 154 words

And I mean that in the kindest way possible. I am currently working with these wizards, and they (and the possibility WPF opens) keep surprising me.

I am well aware that this piece of code is par the course for WPF devs, but I have only dabbled in WPF, and seeing what it can do from visual perspective doesn't mean much until I have seen how clean the UI code looks like. I mean, just take a look at this:

image

All the information that I need to have about how to handle a piece of the UI is right there, and the infrastructure supports working in the way that I think is appropriate. The reason for this post is seeing how context menus works. I was extremely pleased to see how it all comes together in a single cohesive unit.

time to read 1 min | 86 words

I am currently working on an interesting application, basically, rule engine, data + DSL, and other fun stuff. Unfortunately, here is how the UI is right now:

image

Yes, the disclaimer is in the UI.

Therefor, I currently looking for a WPF dev / designer. I am currently in New York, but there is no location limitation.

If you are interested, please contact me.

time to read 1 min | 96 words

Glenn posted the before/after pictures of the Prism Reference Implementation application.

I was very impressed when I saw how they got from the traditional developer styled UI:

StockTrader_Before.png

To this UI:

StockTrader_After.png

Something else that Glenn said couldn't be stressed enough, this metamorphosis has happened in two weeks by a single developer.

I have worked on skinnable (win forms) applications, and that kind of thing just doesn't take just two man weeks, if it is possible at all.

Wow!

This make the WPF story much more compelling.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Design exercise (6):
    01 Aug 2019 - Complex data aggregation with RavenDB
  2. Reviewing mimalloc (2):
    22 Jul 2019 - Part II
  3. Production postmortem (26):
    07 Jun 2019 - Printer out of paper and the RavenDB hang
  4. Reviewing Sled (3):
    23 Apr 2019 - Part III
  5. RavenDB 4.2 Features (5):
    21 Mar 2019 - Diffing revisions
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats