Flex 2 To Flex 3 Migration Problem with Web Services

Tuesday, August 19 2008         No Comments

Today I basically spent the vast majority of the day fighting an annoying an unexpected problem. We migrated our app from Flex Builder 2 to Flex Builder 3 and after some changes here and there it appeared everything worked. Then one of the developers discovered that a Save method was triggering an error dialog.

We started to look into and and essentially lost the day to the problem.

The call today looks like this:

service.SavePlan(projectVo.guid, xmlString, userGuid);

Where service is a WebService class. Notice the xmlString variable.

After spending a lot of time with Fiddler, Soap Sonar, and Firebug only to conclude I still didn't have a clue why the actual call was returning a 200, but had zero content, I stumbled across a few lines of code buried at the bottom of our ASP.NET Global.asax.

In essence it was taking any request that had a response that wasn't 200 and had a header that contained SoapAction and setting the response to 200. Stepping into it I found that the server was really returning a 400 error.

Now that I knew the request was actually throwing a 400 error I at least had an idea of where to narrow the scope of my research. Finally, I stumbled upon this blog. Item number 3) is the one that triggered a light bulb. We are using web services, not HttpService, but the description of the problem and something I had seen earlier in Soap Sonar came together.

To prove we were experiencing this problem I simply called escape(xxx) on the XML string we were sending in the Soap body. Sure enough, the server processed the request, and then promptly blew up because the backend didn't know it had to call HttpUtilities.UrlDecode(xxxx).

So the problem is that in Flex 2 the body of the entire request was encoded, but in Flex 3 the XML portion of the body was not encoded, resulting in the server trying to process the incoming XML.

 

del.icio.us Tags: , ,

NHibernate and ASP.NET Problems

Monday, August 18 2008         No Comments

I mentioned before that I was considering different ORM frameworks and finally decided on NHibernate. I made that decision mostly on the fact that I know of a fair number of developers who I respect that have used it and they still say nice things about it.

I knew going in there would be a substantial learning curve and some issues that were going to cost me a lot of time I don't necessarily have. My mental cost/benefit analysis included not only the cost to what I'm working on now, but how I will get payout (in theory) going forward.

Unfortunately I've run into a serious problem long before I think I should have.

I have 4 classes defined: Pricing, Coupons, ErrorCode and Service. All four of these classes represent what I would call reference data. They will not be written to by the application. The application needs to be able to get a specific item out the database and ideally get the entire collection.

I defined my mapping file:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    schema="Test.dbo"
    default-access="field.camelcase-underscore"
    namespace="Ecom.ReferenceData"       >
  <class name="Ecom.ReferenceData.Service, Ecom" table="Services">

    <id name="ServiceID" column="ServiceID"
        type="Int32" unsaved-value="null">
      <generator class="native" />
    </id>

    <property name="ServiceID" column="ServiceID" type="Int32" />
    <property name="Description" column="Description" type="String" length="50" />
    <property name="Detail" column="Detail" type="String" length="80" />
  </class>
</hibernate-mapping>

And then created a unit test (you do unit test right?)

Pricing pricing = _session.Load<Pricing>(1);
Assert.AreEqual(1, pricing.priceID);
Assert.AreEqual(3, pricing.CouponID);
Assert.AreEqual(1, pricing.ServiceID);
Assert.AreEqual(29.95, pricing.Price);

Not exactly a robust test but it did prove that the load worked.

Then I added a test to get the collection:

IList<Pricing> pricingList = _session.CreateQuery("from Pricing").List<Pricing>();
Assert.IsTrue(pricingList.Count > 0);

It also worked exactly as expected. Time to do the rest...

I added the other 3 classes exactly the same way. All 4 correctly do the initial unit test with _session.Load<T>(1);

However, 2 of the 4 fail on the second CreateQuery() test. The error results:

NHibernate.QueryException: in expected: <end-of-text> (possibly an invalid or unmapped class name was used in the query) [from coupons]

Someone please save me from my own stupidity here, but what the heck does that mean?

Remember, this test works fine loading each individual item. There are no nulls in the database. The only thing that is "different" is the use of the schema attribute in my mapping file. I did that because I need to talk to more than one database. All tables are in this example are in the same DB (not that it matters because this query never gets to that point). The Log4Net files are useless since it dies on Compiling Query.... well duh.

After literally a couple of hours of messing with this, I changed my code to this:

ISQLQuery query = _session.CreateSQLQuery("select * from test.dbo.coupons").AddEntity(typeof(Coupon));
IList<Coupon> coupons = query.List<Coupon>();

This code works fine, which once again leads me to believe my mapping file is correct. In fact, all four mapping files are almost identical in that each was created starting from the other. Each table in the DB has a single column primary key (int) defined.

I am hoping that as I move forward things get easier, because if I sink this much time into the simple stuff, this work will never pay for itself.

del.icio.us Tags:

What ORM Tool Should I use

Wednesday, July 30 2008         No Comments

I have a new project and I want to get away from the stored procedure paradigm. I've looked at a couple of the more populate ORM tools out there, but I haven't found anything that really looks like it will fit my needs.

The 1st project is simple, just some forms, user authentication, and user property management. The second is far more complex and will involve heavy usage of XQuery. My intent is to get up to speed on the tool with the first project.

Any recommendations?

Castle.NET

NHIbernate

WilsonORM

ActiveRecord?

Which one will allow me to use XQuery?

del.icio.us Tags:

Flexbuilder Visual Studio and Firebug

Friday, July 11 2008         No Comments

I'm using all three of these on a regular basis. In fact, most days, I switch back and forth many times. I find it frustrating that each one has decided to implement the very common debug steps of Step-In, Step-Out, Step-Over in different ways. In my previous position I had the same trio but with Visual Basic 6 instead of Flex builder and it has an different combination as well.

I know you can change the default key maps for Visual Studio, but that doesn't really solve the problem.

Why is it that the very common task of debugging and stepping through code has to be different in every single environment. Is it a case of "Not Invented Here"? That doesn't really explain Microsoft's penchant for having different key mappings or does it?

How about the next time you build something that is commonly implemented you follow the market leader or at the very least prominently give the tool the ability to change?

del.icio.us Tags:

Using Close Dispose and Finalizers

Saturday, June 28 2008         No Comments

Summary

[this was written against the 1.1 framework]

At some point in your use of .NET you are going find that garbage collection, or rather, the lack of garbage collection is causing you a problem. The most likely scenario is that you have some unmanaged resource that you are trying to access and you can’t. Fortunately Microsoft provides us with the tools to handle these types of situations. In this article I’ll be discussing Finalization, Dispose and the IDisposable pattern, Close and the C# specific Using statement. I will also touch on some garbage collection terms. If you aren’t familiar with any of the terms used I strongly suggest you get hold of a good book on CLR Internals and gain an understanding. The .NET garbage collector can be your friend or your worst enemy.

 
Finalize
Finalization in .NET is the process by which the garbage collector [GC] allows objects to clean up any unmanaged resources prior to destroying the object. When the GC determines an object is eligible for garbage collection it will call that objects finalize method. It is up to that method to close any unmanaged resources. If you have an object that is holding unmanaged resources, but don’t provide a finalize method then you will cause a memory leak in your application as resources will be orphaned with no way to free them.
When an object that is finalizable is created a pointer to it is put on the Finalization queue. When the GC runs looking for objects that no longer have any references to them it also checks the Finalization queue. If an object is in the Finalization queue then that object is not garbage collected. Instead the pointer is removed from the Finalization queue and its Finalize method will be called. The actual call is made by a special Finalization thread. On the next GC the object will be eligible for collection. That doesn’t mean that it will be collected. It is possible for a finalizable object to be moved to a later generation, causing it to live even longer.
This means that finalizable objects take longer to allocate and cost significantly more to free. Make sure you really need that finalizer before you create it.
Declaring a Finalize Method
There are two way to declare a finalize method. Unfortunately if you chose the one below you are given a compiler exception that does more harm that good.
 
Finalizer Example1
      public class FinalizeExample
      {
            private FileStream _fileStream;
            private IntPtr _fileHandle;
            private IntPtr _invalidPtr = IntPtr.Zero;
 
            public FinalizeExample()
            {
                  _fileStream  = File.Create("c:\temp\testfile.txt");
                  _fileHandle = _fileStream.Handle;
            }
            public void WriteToStream(byte logByte)
            {
                  _fileStream.WriteByte(logByte);
        }
            protected override void Finalize()
            {
                  _fileHandle = _invalidPtr;
                  _fileStream.Close();
            }    
      }
If you compile this the IDE will give you an error message:
Do not override object.Finalize.  Instead, provide a destructor.
The Finalizer is NOT a destructor. Ignore the fact that someone at Microsoft is telling you it is. Actually for whatever reason MS chose to call the finalizer a destructor, but it is confusing so don’t think of it that way!
 
Destructor vs. Finalizer
 
A destructor is something that deterministically releases resources [e.g. C++ destructor]. A finalizer is NOT deterministic. The finalize method only gets called when GC happens. I’ll say it again…. The finalize method only gets called when GC happens.
Here’s how you declare the finalizer correctly
 
      public class FinalizerExampleOkay
      {
            private FileStream _fileStream;
            private IntPtr _fileHandle;
            private IntPtr _invalidPtr = IntPtr.Zero;
            public FinalizerExampleOkay()
            {
                  _fileStream  = File.Create("c:\temp\testfile.txt");
                  _fileHandle = _fileStream.Handle;
            }
            public void WriteToStream(byte logByte)
            {
                  _fileStream.WriteByte(logByte);
        }
            ~FinalizerExampleOkay()
            {
                  _fileHandle = _invalidPtr;
                  _fileStream.Close();
            }
      }
It sure looks like a destructor doesn’t it?
 
Finalizer Summary
 
So the finalizer is a way for you to ensure that resources are released when an object is garbage collected. It is NOT a deterministic release of those resources.
  • The finalize method is not free, rather it is an expensive operation.
  • Objects that have finalize methods are promoted to the next generation when the GC determines they are garbage. They are not eligible to be collected until the next GC run.
  • Any objects referenced by the object with the finalize method will be promoted along with the object, which means you will be allocating and holding resources longer than necessary.
  • Finalization can be called in any order the CLR chooses. This means that you should never access another object that implements a finalizer from your finalizer. If you do the other object could be finalized first leaving you with a null reference.
  • Finalize method will be called even if your object’s constructor threw an exception.
 
More Reading
 
Dispose via IDisposable
 
We’ve talked about how to use a Finalize method to clean up your resources. However, the problem with this method is that you can’t call it. It is called by the .NET Framework for you. In order to allow more control over the release of unmanaged resources MS introduced the concept of a Dispose method. They also introduced the IDisposable interface to indicate that a class has a Dispose method available.
Any class that implements IDisposable MUST
·         Implement a finalizer. The reason for this is that Dispose must be called directly by some code. The finalizer exists to handle any case where some code failed to call dispose properly.
·         Call its base class Dispose method (if one exists)
·         Call GC.SupressFinalize in Dispose() to prevent GC from unnecessary finalization steps
·         If called more than once it must not throw an exception
·         May throw an exception if the resource it was attempting to free was already freed.
 
IDisposable Example
 
    public class DisposeExample
    {
        private FileStream _fileStream;
        private IntPtr _fileHandle;
        private IntPtr _invalidPtr = IntPtr.Zero;
        private bool _disposed = false;
 
        public DisposeExample()
        {
            _fileStream  = File.Create("c:\temp\testfile.txt");
            _fileHandle = _fileStream.Handle;
 
        }
        public void WriteToStream(byte logByte)
        {
            _fileStream.WriteByte(logByte);
        }
        /// <summary>
        /// Finalizer to ensure our objects resources are
        /// freed
        /// </summary>
        ~DisposeExample()
        {
            Dispose(false);
        }
        /// <summary>
        /// IDisposable interface implimentation to
        /// </summary>
        public void Dispose()
        {
            //pass true indicating managed resources can be freed as well e.g. our code called
            //dispose instead of the .NET framework
            Dispose(true);
            //prevent Finalization since we already freed the resources
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// Virtual Dispose method that any subclasses will inherit and
        /// override.
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if(!_disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.
                    _fileStream.Close(); //note we called close because it was available
                }
                // Release unmanaged resources. If disposing is false,
                // only the following code is executed.
                _fileHandle = _invalidPtr;
                //thread safety is up to the client!
            }
            _disposed = true;
        }
    }
 
Derived Class
 
A derived class only needs to implement the virtual Dispose method. Like the base class it needs to determine if it can free managed resources (dispose == true) or not. It must also call the base class Dispose to ensure that all resources are freed.
 
Derived Example
 
public class DisposeExampleDerived:DisposeExample
    {
        private bool _disposed = false;
        private IntPtr _unmanagedHandle;
        private IntPtr _invalidPtr = IntPtr.Zero;
        private FileStream fs = new FileStream(@"C:\temp\tempstream.txt", FileMode.Append);
 
        public DisposeExampleDerived(){}
        /// <summary>
        /// Virtual Dispose method that any subclasses will inherit and
        /// override.
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            if(!_disposed)
            {
                //notice we use try/finally to ensure base.Dispose gets called
                try
                {
                    if(disposing)
                    {
                        // Release the managed resources you added in
                        // this derived class here.
                        fs.Close(); //close because they provided close instead of dispose
                    }
                    // Release the native unmanaged resources you added
                    // in this derived class here.
                    _unmanagedHandle = _invalidPtr;
                    _disposed = true;
                }
                finally
                {
                    // Call Dispose on your base class.
                    base.Dispose(disposing);
                }
 
            }
 
        }
 
 
    }
 
Further Reading
 
 
Close
 
Close is essentially a method of convenience. It was apparently added because someone thought developers are more likely to call Close() than Dispose(). The recommendation is that if it makes more sense to call Close on something [e.g. a stream object] then implement a Close method and have it call Dispose.
 
I find the use of the Close method to be just added confusion. If you look closely at the IL for various methods that have a Close method you will see that MS apparently wasn’t really sure about it either. The best thing you can do is to follow the “recommendation”, which is having your Close method call Dispose.
 
Some Confusing Examples
 
SqlDataReader:Close()
The Close() method on the SqlDataReader calls an InternalClose() method, which does not call Dispose. Note that previously we stated the correct way to do this was to have your close call dispose. To make it even more confusing the Dispose() method actually calls the Close() method so for this object the order is reversed.
 
SqlDataAdapter()
This class only contains the Dispose(bool disposing) override. So even in the same namespace we see differences.
 
 
 
 
 
 
 
What do I call
There has been a lot of discussion around what you should call: Close, Dispose or both. If you follow the recommendations from MS about the IDisposable pattern it shouldn’t matter. Close should do exactly the same thing that Dispose does. I don’t call either as I use the Using statement whenever IDisposable is implemented.
 
Using
 
C# has a very convenient way to ensure that a method with IDisposable gets its Dispose method called.
The Using statement. According to MSDN the Using Statement defines a scope at which an item will be disposed.
 
Using Example
 
        public void UsingCalled()
        {
            using (SqlCommand cmd = new SqlCommand("sp_something", new SqlConnection("string")))
            {
                //always supply the commandBehavior!
                SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                while(reader.Read())
                {
                    //do something
                }
 
            } //this will call close/dispose
        }
 
IL Using Statement
 
.method public hidebysig instance void  UsingCalled() cil managed
{
  // Code size       53 (0x35)
  .maxstack  3
  .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand cmd,
           [1] class [System.Data]System.Data.SqlClient.SqlDataReader reader)
  IL_0000:  ldstr      "sp_something"
  IL_0005:  ldstr      "string"
  IL_000a:  newobj     instance void [System.Data]System.Data.SqlClient.SqlConnection::.ctor(string)
  IL_000f:  newobj     instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor(string,
                                                                                          class [System.Data]System.Data.SqlClient.SqlConnection)
  IL_0014:  stloc.0
  .try
  {
    IL_0015:  ldloc.0
    IL_0016:  ldc.i4.s   32
    IL_0018:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlDataReader [System.Data]System.Data.SqlClient.SqlCommand::ExecuteReader(valuetype [System.Data]System.Data.CommandBehavior)
    IL_001d:  stloc.1
    IL_001e:  br.s       IL_0020
    IL_0020:  ldloc.1
    IL_0021:  callvirt   instance bool [System.Data]System.Data.SqlClient.SqlDataReader::Read()
    IL_0026:  brtrue.s   IL_0020
    IL_0028:  leave.s    IL_0034
  }  // end .try
  finally
  {
    IL_002a:  ldloc.0
    IL_002b:  brfalse.s  IL_0033
    IL_002d:  ldloc.0
    IL_002e:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0033:  endfinally
  }  // end handler
  IL_0034:  ret
} // end of method UsingSample::UsingCalled
 
Notice how in the above IL the Using Statement was converted into a Try…Finally to ensure our object gets its Dispose method called.
 
Example 2 Call Close
 
        public void CloseCalled()
        {
            SqlCommand cmd = new SqlCommand("sp_something", new SqlConnection("string"));
            SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
 
            while(reader.Read())
            {
                //do something
            }
 
            reader.Close();
        }
 
IL Close
 
.method public hidebysig instance void  CloseCalled() cil managed
{
  // Code size       47 (0x2f)
  .maxstack  3
  .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand cmd,
           [1] class [System.Data]System.Data.SqlClient.SqlDataReader reader)
  IL_0000:  ldstr      "sp_something"
  IL_0005:  ldstr      "string"
  IL_000a:  newobj     instance void [System.Data]System.Data.SqlClient.SqlConnection::.ctor(string)
  IL_000f:  newobj     instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor(string,
                                                                                          class [System.Data]System.Data.SqlClient.SqlConnection)
  IL_0014:  stloc.0
  IL_0015:  ldloc.0
  IL_0016:  ldc.i4.s   32
  IL_0018:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlDataReader [System.Data]System.Data.SqlClient.SqlCommand::ExecuteReader(valuetype [System.Data]System.Data.CommandBehavior)
  IL_001d:  stloc.1
  IL_001e:  br.s       IL_0020
  IL_0020:  ldloc.1
  IL_0021:  callvirt   instance bool [System.Data]System.Data.SqlClient.SqlDataReader::Read()
  IL_0026:  brtrue.s   IL_0020
  IL_0028:  ldloc.1
  IL_0029:  callvirt   instance void [System.Data]System.Data.SqlClient.SqlDataReader::Close()
  IL_002e:  ret
} // end of method UsingSample::CloseCalled
 
Notice how there is no Try…Finally in this one and we actually call Close not Dispose.
 
Example 3 Call Nothing
 
        public void NothingCalled()
        {
            SqlCommand cmd = new SqlCommand("sp_something", new SqlConnection("string"));
            SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            while(reader.Read())
            {
                //do something
            }
        }
 
IL Call Nothing
 
.method public hidebysig instance void  NothingCalled() cil managed
{
  // Code size       41 (0x29)
  .maxstack  3
  .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand cmd,
           [1] class [System.Data]System.Data.SqlClient.SqlDataReader reader)
  IL_0000:  ldstr      "sp_something"
  IL_0005:  ldstr      "string"
  IL_000a:  newobj     instance void [System.Data]System.Data.SqlClient.SqlConnection::.ctor(string)
  IL_000f:  newobj     instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor(string,
                                                                                          class [System.Data]System.Data.SqlClient.SqlConnection)
  IL_0014:  stloc.0
  IL_0015:  ldloc.0
  IL_0016:  ldc.i4.s   32
  IL_0018:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlDataReader [System.Data]System.Data.SqlClient.SqlCommand::ExecuteReader(valuetype [System.Data]System.Data.CommandBehavior)
  IL_001d:  stloc.1
  IL_001e:  br.s       IL_0020
  IL_0020:  ldloc.1
  IL_0021:  callvirt   instance bool [System.Data]System.Data.SqlClient.SqlDataReader::Read()
  IL_0026:  brtrue.s   IL_0020
  IL_0028:  ret
} // end of method UsingSample::NothingCalled
 
Notice how we are left to the mercy of the GC with this example. We don’t call close explicitly which means our SqlConnection object won’t close for use via the CommandBehavior.
 
There are some subtle things to watch out for when you use the Using Statement. You must make sure that you set the scope correctly. If you don’t you could end up with your object being destroyed either well before you are ready for that to happen, or far too late to do you any real good.
 
There are a lot of details around Finalizers and how the GC works that easily fill a book (in fact a few have been written). I encourage you to take a closer look at the CLR, download Rotor, get an Internals book and most of make sure you understand what your code is really doing.  
 

How Do Browsers Determine If a File is Cached

Thursday, June 26 2008         No Comments

Last week someone asked me how browsers determine if a CSS file is returned from cache or not. My response was admittedly rather lame... So I went to go look up the full answer. The first place I went was the W3C web site. For an organization that helps establish standards for the web you would think their site would be a little less hard on the eyes.

w3chome

 

Caching is established by the HTTP protocol Specification. The HTTP 1.1 specification is available here. Like everything else on the W3C site it is a dense read that will make your head swim with linked references, obscure statements, and general ambiguities [hmmm sounds like my blog]. The answer to the CSS question is that the file fails the "Validation" check and so the browser returns a new one if the file is changed otherwise the response the server gets is a 304 (Not modified) and so the request body is returned from cache.

Let's look at what the W3C has to say about caching.

Section 13 Caching In HTTP

Caching would be useless if it did not significantly improve performance. The goal of caching in HTTP/1.1 is to eliminate the need to send requests in many cases, and to eliminate the need to send full responses in many other cases. The former reduces the number of network round-trips required for many operations; we use an "expiration" mechanism for this purpose (see section 13.2). The latter reduces network bandwidth requirements; we use a "validation" mechanism for this purpose (see section 13.3).

There are two key constraints defined:

  • Eliminate the need to send requests
  • Eliminate the need to send full responses

These two constraints are handled separately via expiration and validation.

Expiration

When we set expiration we are saying that the page/content will no longer be valid after some date. Once past that date the server must request new content. That doesn't mean it will get new content. It just means it must request it.

The primary mechanism for avoiding requests is for an origin server to provide an explicit expiration time in the future

Simple enough right? Most of us who have build anything for the web have some experience with caching. Usually it is something that was cached that we didn't want to be cached. Ironically the spec defines a value that was made to address that exact scenario:

If an origin server wishes to force any HTTP/1.1 cache, no matter how it is configured, to validate every request, it SHOULD use the "must- revalidate" cache-control directive (see section 14)

I'm a little embarrassed to say I've never heard of the must-revalidate cache-control directive.

Validation

When a request has been sent it undergoes Validation. In this case there is a determination if the response is the same or similar enough to the previously sent response that the server does not have to send the original response body again.

When a cache has a stale entry that it would like to use as a response to a client's request, it first has to check with the origin server (or possibly an intermediate cache with a fresh response) to see if its cached entry is still usable. We call this "validating" the cache entry.

Validation occurs through Last-Modified-Date headers or ETags (Entity Tag Cache Validators). There is the concept of "weak" and "strong" validators. Last-Modified-Date headers are considered weak while ETags are usually considered strong, though it is possible to alter that.

Section 13.3.4 contains the rules for when to use Last-Modified vs. ETags.

I've read through this document a few times and each time I come away with more that I didn't know.

For a less dense read check out this document.

Coding in the Dark

Tuesday, June 17 2008         No Comments

Jeff Atwood has yet another great post on developers who tend to lock themselves away and "go dark".

I doubt there is a single developer out there who hasn't experienced this in the extreme. For me, it was when a developer delivered a "complete" feature that was so complex and over engineered that three senior developers struggled to understand what this person was trying to accomplish. The feature worked... sort of. It was almost impossible to test and completely opaque to anyone without days of reading and analysis.

In the end we rewrote the feature by refactoring what was there. The result was about 50% less code and a clean, fairly easy to understand model.

I will quote Jeff:

         "It is effectively impossible to go dark if you're practicing any form of agile software development."

For me, that fact alone fully justifies moving to an agile development process. Dealing with opaque code, whether I wrote it someone else did, is not fun.

 

Site Updated to Graffiti

Thursday, June 12 2008         No Comments

I've upgraded Codeverity.com to Graffiti from Community Server 2007.

Looks like ServerIntellect saved the day by granting permissions to create folders. That is why I host here!

Graffiti can't actually create the directories for new posts, though the db writes work so clicking this link is broken

There are still a few known issues with some of the redirects, but for the most part the upgrade process went well.

How Many Features In a Release

Thursday, June 12 2008         No Comments

As developers when we release code we almost always classify it as n amount of features:

Announcing Release v4:

Auto Login
User Profiles
Reporting
When product management comes to engineering they usually have a list a features they want in the application. Those features may or may not make it into the final release, but they begin their life a feature request.

If you ask your CEO the following question:

"Does the business benefit from adding features or adding value?"

What do you think the answer will be? Unless your CEO is incompetent the answer should always be "adding value".

If we improve our business by adding value then why do we structure development around features instead of value add? Why don't we ask and get the information on what the value add is?

When I was at Staples we had a "quick" project that was to implement real-time credit card authorization. This was some years ago before this type of thing was well known. Development had a lot of concerns about performance, uptime, and what to do when the authorization didn't work because of technical issues. It seemed that we were jeopardizing our lifeblood (purchasing) by adding this feature.

As the lead I asked the question about the value of this project. The answer was that we were loosing something like 13 million a day/week/month (I forget the time frame) to mostly Nigerian fraud and this would put an end to that. Suddenly we had a value add request and not a feature request. It was one of the few times when I felt like I knew exactly the reason for a feature that extended beyond "so and so wants it so we are building it". The value add also went a long way to answering the what if questions that we had.

This post on BDD got me thinking along these lines.

I'll quote the above post:

“That’s the problem,” says Chris. “You’re putting the role first. It’s the value that’s most important. Try this: In order to <deliver some value>, as a <role>, I want <some feature>. Instead of working out why people want a feature, and whether it contributes to the value, now we’re working out who needs a feature, then assigning the story. So our stories are much more focused. If all the stories that contribute to a value are ready, we release.”

Next time you get a feature request convert it to a value and then prioritize it:

"In order to <achieve some value>
As a <role>
I want <some feature>."

Google Goes On Forever

Monday, May 19 2008         2 Comments

I was driving my daughter to buy her a pet frog (yes, a real frog). She's 5 and I promised that once we moved to the house she could have a pet and she wanted a frog. She likes to watch him eat crickets (LOL).

On the way she tells me that if we have a car that was "faster than light and sound" we could just be there, but that it would cost "google dollars".

I laughed and agreed. Where do they get this stuff? I asked what "google" dollars were and she said:

"Oh, google goes on forever"

My thought, after laughing, was my daughter is a marketing dream come true. Google couldn't buy marking like that!