Category: Dev

Stay “So Fresh, So Clean” in Legacy Application Development

The title may not fit until the end of this post, but bear with me. I work in a large legacy .Net application and I felt it pulling me into the depths of its ASP.NET 1.1’ness and decided to write this post to remind myself that I can keep my skills moving forward and still keep the legacy maintained.

I had a new project where I had to dump the configuration data for customers into a file with a human readable format. The purpose of this project is to allow someone to compare the configuration data from environment to environment to verify the configuration is maintained and correct as it makes its way to production. The comparison is done outside of the project and the system with a third party diff tool. The configuration data is held in database tables so a simple dump of the data from the table to the file is what I set out to do.

There is already a project in the application that handles this type of scenario, but the code is “So Dirty, So Complex” and a nightmare to maintain. It’s also rigid, full of hard dependencies, and so unreliable that no one uses the tool. Hence the reason I was tasked to work on the use case. Since this is such a simple use case I wanted to create new code that will provide a solution that is easier to maintain and extend and get rid of a very small piece of the stench in this legacy app.

There are three basic parts of my solution:

  • Data Retriever – code to retrieve the data, in this instance, from a database
  • Serializer – code to serialize the Data Retriever into the Output
  • Outputter – code to write the Serializer to the output format, in this instance a file

I am using ADO.net and DbDataReader for database agnostic data streaming. The Serializer is currently dependent on DbDataReader, but it would be simple at this point to introduce a Mapper to pre-process the data stream and pass a DTO instead of reader to Serializer. I didn’t do this in the first iteration because it didn’t provide enough value for the time it would have taken to figure out a way to abstract DTOs in a way that made the solution flexible. The Outputter is basic System.IO and there is no interface for it at this point. We could provide an Outputter interface then we could output to other formats say to another database table or posting to a service.

In the Serializer, I decided on JSON as the human readable format, because it is a standard format and easier to read than XML, IMHO. Also, its a chance to bring new concepts into this legacy application that has no exposure, that I know of, to JSON. I tested serialization solutions side by side, a custom JSON serializer I coded by hand and JSON.net. My test was to just through the same data set at both solutions in a test harness and record and compare timing. I was mindful of using some semblance of scientific method, but my test environment runs on my local dev box that has a lot going on, so the results are not gospel and can vary depending on what’s running in the background.

After running my tests and analyzing the results and my limited research I chose to use the custom serializer. Although JSON.net is an awesome framework, the custom was a better fit for this iteration and here are my observations and reasoning why I went this direction:

  • The custom was more than an order of magnitude faster in my unscientific test. With JSON.net there is an additional step to create an IEnumerable<dynamic> to facilitate serialization so we probably went from O(1) to O(2), but I’m not sure without seeing the JSON.net internals. There may also be optimization in my JSON.net usage that could make it faster, but I had to do this project quick and simple. Without going into the gory details here’s the results of average time over 100 iterations of serializing the test data:
    • Custom Time:    00:00:00.0004153
    • JSON.net Time: 00:00:00.2529317
      This difference in time remained near the same in multiple runs of the test.
  • JSON.net output is not formatted. It’s all one line and defeats the human readable aspect of the project. This is probably configurable somehow, but I didn’t research.
  • I don’t need to deserialize and don’t have to worry about the complexity of deserialization. If I did, I would probably go with JSON.Net.
  • I am not sure if we are authorized to use JSON.Net in production.
  • We are serializing flat data from one table or view (no table join object mapping) and we don’t have to worry about the complexities of multi-level hierarchies or I’d choose JSON.net.

In the end even though I tied myself to a specific implementation I built in extendability through abstractions. We can later swap serializers and also build new dumps based on other tables pretty easily. I could see possibly adding a feature to import a dump file for comparison in the system instead of having to use an external tool. This could also be the basis for moving data from system to system in a way that will be much simpler than the previous project. Taking the time to look at multiple solutions presented me with areas that I should think about and prepare for extension without going overboard with abstractions.

The real point is to try more than one thing when trying to find a solution to a problem. Compare solutions to find reasons to use or not use solutions. Don’t pick the first thing that comes your way or comes to mind. Spend a little time learning something new and experimenting or you will rarely learn anything new on your own and will stay a slave of Google (no disrespect as I lean heavily on Google search). This is especially important for engineers dealing with enterprise legacy applications. Don’t let yourself get outdated like a 10 year old broken legacy application. Stay “So Fresh, So Clean”.

Given the Keys to Merge

Today we were told that the Dev on Production Support will be responsible for merging branches. Branching here is a little different than I’m used to. Usually, there is a trunk, main, or master branch that acts as the root that release or feature branches are branched off of. Here release branching is not done from trunk, but a previous branch. So, if we are currently working on release 5.0 and need to start on release 5.1, an new branch will be created off of the 5.0 branch. If there is concurrent development in both branches then the new 5.1 branch needs to be kept in synch with the 5.0 branch, so we merge the 5.0 changes to the 5.1 branch. I am not sure how or even if we merge everything back to trunk or even if we use trunk.

With this scheme when there is a stockpile of changes it is difficult to reconcile all of the potential merge conflicts. If there was a change to the same file of the branches being merged, the merge can get a little hairy trying to reconcile everything. It was decided to merge more often so you don’t have to face a mountain of merge issues. The Production Support Dev will merge branches preferably daily. Since we all rotate Production Support duties, that means the entire team has the keys to merges.

My little brain always has questions and my thought was why don’t we just merge when we have a change complete. If you make a change in a branch, you should issue a merge request to the team (ala Git, even thought we are an SVN shop). A merge request is simply a message to the team asking them to code review the change. If the change passes coded review, the Dev can merge changes related branches. Well it seems that merging is time consuming in our environment. I haven’t done it yet, but our tech lead said that we could merge our own changes if we have time. I assume that this means that under the pressure to get the release complete there is usually no time to merge. I will try it myself and record the time, if I have time :). Although, my production code dev days are limited, so I won’t have a chance to get a lot of opportunities to put it to the test.

Main Line Development

At my previous employer we did main line development. This basically means we developed directly in main (i.e. trunk). Main wasn’t stable and always had the latest changes of the next release. When we deployed a release we would cut a release tag off of the commit in main that was deployed to production. There would always be a tag that contains the currently deployed code.

Any branching outside of the tag release branching was frowned upon and were asked to limit branching (e.g. you better not branch) because merging was thought to be evil. So, we didn’t do concurrent development on multiple releases. The focus was entirely on the current release. When the release was QA validated, we’d cut the release branch and move on to the next release. This meant that as the release slowly came to a close we were sometimes left twiddling our thumbs while we waited on QA validation and release branching.

If we need to do a production hotfix, we would cut branch off of the current production release tag, make the fix, QA validate it, cut a new release tag, merge changes to main.

It was a very clean process, but I remember having a strong desire to cut feature branches so I could work on the next thing.

Feature Toggles

Which bring up Feature Toggles/Flags. Feature Toggles would allow us to get the best of both worlds. Basically, you add a bit of code to indicate if a particular change is active. In fact the active state can be set in configuration, so IT Operations could actually enable and disable new features and changes with a simple config change. With Feature Toggles we get to do main line and concurrent development at the same time. I have only heard of Feature Toggles in the context of other development stacks like Java. I wonder if there are any .Net shops out there successfully using Feature Toggles?

Multiple PostBacks in ASP.NET WebForms

Here are some, not all, reasons why there would be multiple PostBacks on a page:

  • Handling an event multiple times
    • AutoEventWireup = true in Page declaration and manual wire up event in Page Init. Check your codebehind for the old ASP.Net 1 style of registering events in system generate code.
    • Having control’s AutoPostBack = true while also doing an explicit PostBack in another control event.
  • Custom event JavaScript that doesn’t cancel the click event allowing a double post.

Debugging tips:

  • Do an HTTP trace to view the double PostBack requests.
  • Debug and add watch for Request.Form[“__EVENTTARGET”] to find control initiating PostBack.
  • HTML Validate your page, PostBack could be caused by bad markup

Lastly, this is a little hack that may help turn off double PostBacks temporarily.

     <form id=”Form1″ runat=”server” onsubmit=”Q++; if(Q==1){return true;} else { return false;}”>

Formalized Versioning

Phil Haack did a post about SemVer 2.0, a formal specification for public API versioning. I think it’s a novel idea as it puts a name and formal structure to what a lot of dev shops I know have been doing. It also allows packaging tools to standardize, like the work Phil talks about with NuGet.

I have added “integrating SemVer and NuGet into CI” to my very long list of things to do for my main side project. That list just keeps on growing.