Archives for: March 2005, 08

08/03/05

Permalink 07:12:18 pm
Categories: Programming, .NET, XPO

Improving XPO scalability with ASP.NET

The current version of Developer Express XPO has a Session object that handles one connection to the database together with an object cache for that session. Technically, the Session is a pivotal point in the XPO architecture, all object handling requests go through a Session object.

Recently it came to my attention that some people regard it as a great problem that the Session object is tightly bound to a database connection. By default, this is a direct association: you can create more than one session object in an application, which will result in more than one database connection. If there are many clients, implemented with XPO, accessing a central database, there'll be as many database connections as there are clients. Not necessarily a completely unusual situation, and in the domain of client/server and multi tier applications, respectively, there are numerous ways to implement things differently, if needed. Personally, I tend to prefer application server designs these days, where things obviously scale differently in this regard.

The real problem is most clearly visible when thinking about ASP.NET applications. To make XPO data available to an ASP.NET application, there are three general approaches, as detailed nicely in this article from the XPO online help: (a) one global XPO session, (b) one XPO session per ASP.NET session and (c) one XPO session per request. There isn't much to say (apart from what's already said on that page) about (a) and (c), but (b) is of interest: while it seems to be the perfect solution in terms of manageability (certainly better than (a)), it has its drawbacks where performance is concerned because the multiple Session objects can't share an object cache and, much worse, because the lifetime of an XPO session also defines the lifetime of a database connection.

Of course it would be nice if the session had a mechanism that would simply drop the current connection every time it's finished using it. With connection pooling, as employed by default by the SqlClient, the overhead for getting a new connection would be small but resources could be used much more efficiently when database connections would only be acquired if (and for the time they are) needed. This functionality is missing in the current XPO version. It could be relatively easy to make the necessary changes in the XPO source code, I'm still looking into this.

Until that point, there's a simple solution that works nicely in many cases: When the database connection that's used for a session is closed, that connection is returned to the connection pool and can be reused elsewhere. Interesting enough, XPO already contains the code that will re-establish the connection before it's needed the next time. The important thing is that you must use a line like this:

// close the inner connection
mySession.Connection.Close();

This is not the same thing as mySession.Disconnect();! You'll need to add a line like that in all places where you know that your work with the session has been done for the moment. It's very well possible, for example, to access the session to build a collection of objects, make sure they're loaded (e.g. by accessing one of them), close the connection and continue to work with the objects! There's nothing much that can go wrong here because XPO will always re-establish the connection if it's needed after all.

In a simple test I made, this approach worked nicely in the ASP.NET scenario I was talking about. I restricted the connection pool to two connections and I was able to access the application with five clients nevertheless, because connections were reused from the pool by all five Session objects.

I hope this will prove helpful for someone!

Permalink 04:34:17 pm
Categories: General

The Tyranny of Email

I just read these really interesting articles on Ole Eichhorn's blog: The Tyranny of Email and the followup, Tyranny revisited. They aren't new, but they are good and I hadn't seen them before, so I thought I should pass this on. These articles are really about efficiency working with modern means of communications and I couldn't agree more with most of what is said.

Permalink 01:02:10 pm
Categories: Programming, .NET

What are Generics good for, anyway?

I have received several e-mails asking me about the real use of Generics. Why I like them so much and what makes them such an interesting feature in .NET 2.0. Programmers who use one of many other languages may not have had contact with anything similar to Generics, so I guess that's quite a legitimate question.

Generics are one of the features of the next version of the CLR (Common language runtime), as delivered by Microsoft with .NET 2.0. They can currently be used in the beta and CTP releases of Visual Studio .NET 2005, as well as (in part) in the Mono Project.

Now, to explain the use of Generics I thought I'd just use a small and simple sample. If there's enough interest, I may write other articles on more advanced topics surrounding Generics.

In a project of mine, I used to have some methods that were able to restrict values to a specific range, given as a bottom and a top value. The methods I had looked like this:

public int RestrictValueTop(int value, int top) {
  return value < top ? value : top;
}

public int RestrictValueBottom(int value, int bottom) {
  return value > bottom ? value : bottom;
}

public int RestrictValue(int value, int bottom, int top) {
  return RestrictValueBottom(RestrictValueTop(value, top), bottom);
}

Okay, these three methods complement each other very nicely, so there's no problem with this. The problem was that I needed similar methods for several other data types, like double, decimal, DateTime and even other integer types like Int64. The solution was to copy and paste the methods and change the data types. Now, every time I would need support for yet another data type in the same way, I'd have to create a new set of these three methods.

This is the kind of problem that Generics offer a solution to: I'm able to write a method that can work with more than just one specific data type. But wait! Haven't we been able to do the same thing for a long time? Couldn't the method look like this:

public IComparable RestrictValueBottom(IComparable value, 
  IComparable bottom) {
  return value.CompareTo(bottom) > 0 ? value : bottom;
}

Right, it could be done that way. But there are several problems with the types here, because we can't be sure that the two types passed in as value and bottom are the same (as they need to be for the CompareTo method) and we also can't be sure (as callers of the method) that the type we get returned is the one we expect it to be.

The difference in the Generics approach is this: while the legacy "typed" method always works with a specific type and the interface method works with a type that's never really known for sure, Generics have you specify the type you use at the point in code where you use the method. In the Generics form, that same method would look like this:

public T RestrictValueBottom<T>(T value, T bottom) {
  return Comparer<T>.Default.Compare(value, bottom) > 0 ? value : bottom;
}

The specific type are replaced by a placeholder, T in this case. Although T is often used throughout documentation and samples, there's no need to call the placeholder that. In fact, as soon as more than one placeholder is in place, one should obviously think about giving more meaningful names to them.

Now, if you please disregard the exact syntax of the comparison operation itself (the reason why it's done this way is very well explained here), the method is much same as it used to be. The real difference is that the method is completely typed, as the compiler knows one thing about the types that must be passed in to the method and that are returned: they are the same types, as they are being represented by the same placeholder. A call to this method might look like this:

int foo = RestrictValueBottom<int>(5, 10);

By "passing in" the correct type information between the angle brackets, you define the needed type at the time of the method call. The compiler makes sure you adhere to that definition once you made it, but still your method can be implemented in a type-independent way. That's the magic of Generics!

This is it for now. Please feel free to comment on this or get back to me by e-mail if you have questions about Generics, maybe there'll be more to come!

Enter your email address:

Search

Oliver
MVP logo
March 2005
Sun Mon Tue Wed Thu Fri Sat
 << < Current> >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31