ESB Series: Part 5

Been a really crazy month with a lot of projects all going into production at once. Finally had some time to blog about the progress on my WCF based ESB: http://www.iserviceoriented.com/blog/post/Building+Our+Own+ESB+-+Publish+Subscribe+Part+5.aspx There's been a ton of interest in the project for something that is still very early on. Thanks to everyone who has provided feedback so far.
Posted by Jesse Ezell with no comments
Filed under: , ,

Articulate '09 Product Launch

 

The Articulate team has released its '09 product suite. Our team has grown quite a bit since our last releases. Congrats to everyone!

If you haven't seen Articulate's tools, check them out here:

http://www.articulate.com

We won a ton of awards with the last suite and this one blows the previous out of the water. Good times ahead.

Posted by Jesse Ezell with no comments
Filed under: ,

Configuring WCF Performance

Because the WCF team wanted to provide something secure out of the box and allow inexperienced developers to get up and running quickly, WCF will not perform well without tweaking. Here's a little help with the less obvious settings:

 http://www.iserviceoriented.com/blog/post/Configuring+Performance+Options+-+WCF+Gotcha+3.aspx

 

Posted by Jesse Ezell with no comments
Filed under:

ESB Series Part 4

Long awaited part 4 of my WCF based ESB series is up:

http://www.iserviceoriented.com/blog/post/Building+Our+Own+ESB+-+Publish+Subscribe+Part+4.aspx

 Code is being hosted on GitHub now for anyone that wants to browse and get some ideas (link to the source is at the bottom of the post). The ESB framework is coming along nicely.

Posted by Jesse Ezell with 1 comment(s)
Filed under: ,

Entity Framework: Right Problem, Wrong Place

I was listening to the recent .NET rocks episode about the Entity Framework advisory council and it was interesting to hear the team's point of view and the problems they are trying to solve with the Entity Framework. They have nice goals, but there is a fundamental problem here that some of the original database gurus like C.J. Date make quite clear. SQL is flawed. It's not that we need a million object relational mappers or that we need to look at our databases in terms of objects. In fact, that's the opposite of what the relational model was intended to do. When E.F. Codd invented the relational model, he intended for the database to be a collection of facts with relationships to other facts... not a collection of objects. The relational model was supposed to provide a way to look at and work with these facts in different ways, but SQL and modern RDBMS's fall short of what they were supposed to do. Somewhere along the way, the original plans were lost. Instead of building a truely relational storage system, vendors jumped on the semi-relational SQL model. The SQL model ties physical structure closely to the logical data model, which is where a lot of problems start coming into play. This leads to the situations we've all seen where we need to denormalize the data model to get decent performance numbers.  It seems to me that the solution to the problem should not start with mapping the data to objects, it should start inside SQL Server itself, transitioning from the flawed world of T-SQL to a true implementation of the relational model as it was intended, a world where the physical model is truely detatched from the logical model.

Posted by Jesse Ezell with 6 comment(s)
Filed under: , ,

HealthVault Uses XML Storage

Via EricGu:

From the "perhaps this might be interesting" file...

Since the end of the HealthVault Solution Providers confererence in early June - and the subsequent required recharging - I've been spending the bulk of my time working on HealthVault data types, along with one of the PMs on the partner team. It interesting work - there's a little bit of schema design (all our data types are stored in XML on the server), a little bit of data architecture (is this one data type, or four?), a fair amount of domain-specific learning (how many ways are there to measure body fat percentage?), a bit of working directly with partners (exactly what is this type for?), a lot of word-smithing (should this element be "category", "type", or "area"?), and other things thrown in now and then (utility writing, class design, etc.). [1]

Definitely in the "interesting file." Please post more details :) I would love to hear more about this.

[1] http://blogs.msdn.com/ericgu/archive/2008/07/29/healthvault-data-type-design.aspx

 

Posted by Jesse Ezell with no comments
Filed under: , ,

Agile Development: Warning Signs

Alok Srivastava has an excellent post discussing agile development and areas that can put agile projects at risk. I'm currently doing clean up on an agile project gone south, and I wholeheartedly agree that the issues he points out should be warning signs if you are considering agile development. That's not to say that agile is bad by any means, just that you should think carefully before you make the jump, especially if your project will have the issues Alok mentions:

http://blogs.msdn.com/isv/archive/2008/07/29/agile-methodology-and-new-product-development-four-key-issues.aspx

 

Making the Possible More Impossible

Jared Parsons thought it would be nice if we could have a ReadOnlyList object in our generic template instead of IEnumerable. I think that's an excellent idea, so a few minor modifications and we have an even better solution, not requiring the generic constraint TWrite : TRead:

    public interface ILockedObject<TRead, TWrite> 
    {
        void Read(Action<TRead> action);
        void Write(Action<TWrite> action);
        void Replace(ReplaceAction<TWrite> action);
    }
        
    public class ReaderWriterLockedObject<TRead, TWrite> : ILockedObject<TRead,TWrite>
    {
        public ReaderWriterLockedObject(TWrite value, Converter<TWrite, TRead> makeReadOnly)
        {
            MakeReadOnly = makeReadOnly;
            _value = value;
        }

        public Converter<TWrite, TRead> MakeReadOnly
        {
            get;
            private set;
        }

        TWrite _value;
        ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
        
        #region ILockedObject<T> Members

        public void Read(Action<TRead> action)

        {
            _rwLock.EnterReadLock();
            try
            {
                action(MakeReadOnly(_value));
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }

        public void Write(Action<TWrite> action)
        {
            _rwLock.EnterWriteLock();
            try
            {
                action(_value);
            }
            finally
            {
                _rwLock.ExitWriteLock();
            }
        }

        public void Replace(ReplaceAction<TWrite> action)
        {
            _rwLock.EnterWriteLock();
            try
            {
                action(ref _value);
            }
            finally
            {
                _rwLock.EnterWriteLock();
            }
        }

        #endregion
    }

    public delegate void ReplaceAction<T>(ref T value);

 

Oh, and here is a ReadOnlyList<T> class to go along:

        public class ReadOnlyList<T> : IEnumerable<T>
        {
            IList<T> _list;
            public ReadOnlyList(IList<T> list)
            {
                _list = list;
            }

            public T this[int index]
            {
                get
                {
                    return _list[index];
                }
            }

            public int Count
            {
                get
                {
                    return _list.Count;
                }
            }
            
            #region IEnumerable<T> Members

            public IEnumerator<T> GetEnumerator()
            {
                return _list.GetEnumerator();
            }

            #endregion

            #region IEnumerable Members

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return _list.GetEnumerator();
            }

            #endregion
        }

So now we can do this:

ReaderWriterLockedObject<ReadOnlyList<Customer>, List<Customer>> lockedObject = new ReaderWriterLockedObject<ReadOnlyList<Customer>, List<Customer>>(l, c =>  new ReadOnlyList<Customer> (c));            

If we really want to be slick, we could take it a step further... protecting the elements inside our list:

ReaderWriterLockedObject<ReadOnlyList<ReadOnlyCustomer>, List<Customer>> lockedObject = new ReaderWriterLockedObject<ReadOnlyList<ReadOnlyCustomer>, List<Customer>>(l, wl =>  new ReadOnlyList<ReadOnlyCustomer> (wl, wc => (ReadOnlyCustomer)wc)); 

Making the Possible Impossible

Have you ever gone to a restraunt with a menu that was just too big? Every once and a while I wind up at a place with a huge menu and it takes forever to choose what kind of food I'm going to eat. That's not a problem when I go to a steak house. When I go to a steak house, I know exactly what I want. A rib-eye medium well with a side of mashed potatoes. Removing options always makes it easier to choose the right thing.

Programming is the same way. A lot of complexity in code exists only because we give ourselves too many options. For instance, consider the following code:

List<object> myList = new List<object>();

public void DoSomething()
{
  foreach(object o in myList) { Console.WriteLine(o); }
}

public void DoSomethingElse()
{
  myList.Add(new object());
}

This all looks fine and dandy, until two threads hit these methods at the same time and your app crashes. We can try to make this better like so:

public void DoSomething()
{
  lock(myList)
  {
    foreach(object o in myList) { Console.WriteLine(o); }
  }
}

public void DoSomethingElse()
{
  lock(myList)
  {
    myList.Add(new object());
  }
}

Which again works, but you always have to remember to lock the object. Some times you might forget. Why? Because you can. Nothing in the compiler and nothing in the .NET framework will tell you that you have to lock the object, it just assumes you are a threading wizard. There must be a better way... a way that we can gaurentee that we will never forget to lock our objects, but not make our code a complete mess at the same time. How about explicitly coding our intentions. Something like:

public void DoSomething()
{
  myList.Read(list =>  {
    foreach(object o in list) { Console.WriteLine(o); }
  });
}

public void DoSomethingElse()
{
  myList.Write(list =>  {
    list.Add(new object());
  }
}

Now, you might look at this code and say, "But I could still write to the list in the read block". Well, again, that is only if you give yourself that option. We can prevent that kind of situation completely with this little class I put together after reflecting on some comments from Eyal (http://blogs.microsoft.co.il/blogs/eyal/archive/2008/07/27/esb-on-iserviceoriented.aspx):

    public interface ILockedObject<TRead, TWrite> where TWrite : TRead
    {
        void Read(Action<TRead> action);
        void Write(Action<TWrite> action);
        void Replace(ReplaceAction<TWrite> action);
    }

    public class ReaderWriterLockedObject<TRead, TWrite> : ILockedObject<TRead,TWrite> where TWrite : TRead
    {
        public ReaderWriterLockedObject()
        {            
        }
        public ReaderWriterLockedObject(TWrite value)
        {
            _value = value;
        }
        TWrite _value;
        ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
        

        public void Read(Action<TRead> action)
        {
            _rwLock.EnterReadLock();
            try
            {
                action(_value);
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }

        public void Write(Action<TWrite> action)
        {
            _rwLock.EnterWriteLock();
            try
            {
                action(_value);
            }
            finally
            {
                _rwLock.ExitWriteLock();
            }
        }

        public void Replace(ReplaceAction<TWrite> action)
        {
            _rwLock.EnterWriteLock();
            try
            {
                action(ref _value);
            }
            finally
            {
                _rwLock.EnterWriteLock();
            }
        }

    }

    public delegate void ReplaceAction<T>(ref T value);
 

Now simply change your code to define the list as:

ILockedObject<IEnumerable<object>, IList<object>> _list = new ReaderWriterLockedObject<IEnumerable<object>, IList<object> >(new List<object>());

And it will be impossible for you to access the list without locking it and impossible  for you to write to the list when you requested a read lock (ok, not impossible because you could make a bonehead move and cast it back to list or something, but it is much harder to mess up now). You'll still need to deal with other threading issues, but you'll have one less bad choice to worry about.

All Clouds Are Not Made Equal

As we rollout Microsoft Online Services this becomes a crucial factor especially when you begin to delve in to the laws and regulations of each country and how they implement data privacy.

What’s my point here? My point is that all clouds are not made equal and it’s not a simple thing to flip from being a consumer cloud vendor to an enterprise cloud vendor. The rules and expectations are very different. Flipping the other way, enterprise to consumer is a damn sight easier I’d say.

[1] http://blogs.msdn.com/stevecla01/archive/2008/07/25/are-all-clouds-created-equal.aspx

Posted by Jesse Ezell with 1 comment(s)
More Posts Next page »