newtelligence poweredRSS 2.0
# Tuesday, August 18, 2009

On Sunday, August 16, I competed in the 2009 Pigman Half Ironman, which turned out to be my first bad weather event. How bad was the weather? 20mph winds gusting to 30 with rain. I’m pretty sure I saw a couple of people attempt to ride out on the bike leg, only to turn it around and call it a day.

I woke up at 5am to see it dark and drizzling. My the time I made my way down to the car, it had stopped raining. I got dropped off and proceeded to wait in line to get body marked and chipped. I would have preferred it if I could have put my stuff down in transition and then go get marked and chipped.

I had just finished getting setup, which thankfully included getting my stuff in plastic bags and covered, when the first down pour hit. At least it was 70 out. The rain let up while I was waiting in line to use the bathroom. I headed back to finish my last minute preparations when I heard that transition was being closed, so I pulled on my wetsuit and headed down to the beach.

Then down pour number two happened, and made the first down poor look like a light drizzle. I ended up hiding under/behind a large tree with others, so I could finish putting on my wetsuit. The mandatory pre-race meeting was going on, but I didn’t feel like leaving the shelter of my tree to go stand on the beach. I guess nothing too important was said as I managed to finish the race without incident.

The second down pour subsided and I decided to go warm up in the lake, which was warmer then the pool I usually swim in (although the event was still fully wetsuit legal). I don’t know why, but I really don’t feel like warming up much. I think I’m too excited, but I still probably got in at least 100m. Since it was so warm, I didn’t have to get my face used to the water for a change, which was nice.

The swim was a time trial start, after the pro’s had a mass start. My first two races had me going soon after the pros, but this time around, I was in one of the last waves to go. When a wave was called up, everyone lined up, and started at 3 second intervals.

I was feeling pretty good in the the water, especially in the first 400m or so. My GPS backs this up, as that was the fastest I swam. I don’t know what happened after that, but I did slow down. I didn’t feel too tired, and my arms were not feeling all that bad either, but I was going slower, but still passing quite a few people. The waves in front of me were black, pink, red, and then purple, and I know I passed a couple of purple swim caps. I ended up finishing the swim around 35 minutes, which was 109th overall. I would have liked to see my time closer to 30 minutes, but I’ll take my time.

The theme of slow as molasses T1’s continue with this race, although the monsoon was a contributing factor. I got my wetsuit down to the waist, and was able to run most of the way to my bike, which was a marked improvement. I also got my wetsuit off in short order, and threw it into a garbage bad and off to the side (I was on the end of the transition rack). The first thing that took a heck of a long time, was putting on a long sleeve shirt to act as a base layer. It was next to impossible to pull it down over my wet body, in the rain, but eventually I got it on after hopping around on one foot turning a circle a couple of times. After that I tried to dry off as I put my shoes on (what was I thinking, it was raining out), and get the rest of my stuff together, while trying to keep everything else dry. At a point I think I stopped caring about speed, and given how wet I was, I should have stopped caring about keeping things dry.

After my 7 minute T1 (which looks to be the 16th slowest), I was out on the bike, and heading directly into the monsoon. The iBike was reading 25mph winds, plus there was the rain. The visor on the aero helmet worked wonderfully, and I only got rain in my eye once, which was due to a cross wind. Wind is not my friend I’ve decided. It completely demoralizes me riding into a head wind. Even with a north bound section on the first half, I was still able to pull a negative split (19mph vs. 20.9mph), although I didn’t have much left in me for the run.

Trying to avoid the melt-down I had from my last race, I set my pace goal of 8:00/mile, as was able to maintain that with a little bit of effort. Unfortunately, I realized that I was only able to do that pace because of a tailwind as I turned around and the half way point. I immediately dropped to an 8:30/pace. I had been walking every aid station to make sure I was getting enough fluids, but now I was looking forward to taking a break from running.

Final Results

 

Time

Overall Place

Overall Pct

Age Group Place

Age Group Pct

Swim 35:05 109 20.6% 12 29.3
T1 7:04        
Bike 2:44:12 82 15.5% 11 26.8
T2 3:28        
Run 1:56:16 141 26.6% 12 29.3
Total 5:26:03 110 20.8% 15 36.6

 

Up Next

I’m looking at two Olympic distance events to finish out my season. Considering how much training I have been doing, I should do pretty well in those two events. I now realize that the amount of training I have been doing in preparation for the half-iron events has not been enough to meet my goals, which is an important lesson. Hopefully I can look back in 13 months and say, I’m glad I learned that in 2009 instead of 2010.

Tuesday, August 18, 2009 4:07:41 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Fitness
# Saturday, August 01, 2009

Almost a year ago I found a script for a stored procedure that allowed you to compare two tables in SQL. Today I’ve been working on some data verification, and made really good use out of this script. I couldn’t find it on my blog, so I don’t think I’ve posted this before. Unfortunately, I did not save the original author of the script or where I got it from.

One thing that I wish it could do was work on Table variables, but beggars can’t be choosers. Instead, I just create #TempTables and pass them into the stored procedure, and it works just fine. This lets you define either one or both of the tables you need to operate on, and write complex queries to populate the temp tables.

ALTER PROCEDURE [dbo].[tsi_sp_util_CompareTables](@table1 varchar(100),

@table2 Varchar(100), @T1ColumnList varchar(max),

@T2ColumnList varchar(max) = '')

 

AS

 

-- Table1, Table2 are the tables or views to compare.
-- T1ColumnList is the list of columns to compare, from table1.
-- Just list them comma-separated, like in a GROUP BY clause.
-- If T2ColumnList is not specified, it is assumed to be the same
-- as T1ColumnList.  Otherwise, list the columns of Table2 in
-- the same order as the columns in table1 that you wish to compare.
--
-- The result is all rows from either table that do NOT match
-- the other table in all columns specified, along with which table that
-- row is from.

 

declare @SQL varchar(8000);

IF @t2ColumnList = '' SET @T2ColumnList = @T1ColumnList

set @SQL = 'SELECT ''' + @table1 + ''' AS TableName, ' + @t1ColumnList +

' FROM ' + @Table1 + ' UNION ALL SELECT ''' + @table2 + ''' As TableName, ' +

@t2ColumnList + ' FROM ' + @Table2

set @SQL = 'SELECT Max(TableName) as TableName, ' + @t1ColumnList +

' FROM (' + @SQL + ') A GROUP BY ' + @t1ColumnList +

' HAVING COUNT(*) = 1'

 

exec ( @SQL)

Saturday, August 01, 2009 1:06:49 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Sql
# Monday, July 27, 2009

I was reading a short post by Ayende on coding things that make the giant red warning light go off in your head. One of the examples he gives is using a WCF service in a using block, but he didn’t go into any detail as to why that is bad. A quick Bing search led me to this article by Dan Rigsby entitled Don’t Wrap Wcf Service Hosts or Clients in a Using Statement.

The gist of it is that IDisposable is implemented in an uncommon way in some of the WCF objects. A common problem is that if the service fails to open due to an exception, the Dispose method will be called. In Dispose, a call to Close() is made, which will throw an InvalidOperationException and a CommunicationObjectFaultedException. Dan’s article has some code that shows what's going on that makes this a little more clear.

So it’s not the end of the world if you use a Using statement, but you will get some unexpected exceptions at times. You just need to be aware of how Dispose works and the exceptions that can be thrown and act accordingly.

Monday, July 27, 2009 3:02:33 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Programming

The Spirit of Racine Half Ironman, held on Sunday July 19th, 2009 was the second Triathlon of my season (and career). This was my first Half Ironman, and quite a different experience in terms of the required effort. I finished in 256th place overall with a time of 4:48:59, which was a little slower then my realistic goal of 2:45 (which assumed an actual 1.2 mile swim, see below).

Registration and the day before

I arrived at the race expo in downtown Racine around 3:30 PM on the Saturday before the race. The registration process was pretty straight forward, although they were out of small and medium size shirts, which didn’t bother me. However on the forums and the blog sphere, several people were acting as if they had been defrauded, with one guy talking about filing a complaint with his credit card company. People, relax, it’s a T-Shirt, hardly something to get worked up over. I also read that you could contact the race director and get a shirt mailed out to you.

The expo was pretty decent, but all I have to compare it to was the tiny expo for the Capital View Triathlon. After hearing that the water temp was a balmy 59 degrees, I opted to pick up a neoprene swim cap. I also came across some good deals on Triathlon/Transition bags, and figured it was time to upgrade from my small duffle bag to something more practical. I also stopped and talked with a Comp-u-Trainer rep for a bit, as I’m thinking about getting one, but they are kind of pricy.

My parents are from Racine, so I have allot of family down there, which was awesome because I got a free place to stay and a really good dinner. A special thanks goes out to my Aunt and Uncle for letting me stay, and the spaghetti feast they prepared. I am thinking about eating my big meal earlier in the day to avoid certain issues I will talk about below.

Pre-Race

Woke up at 5:10am, grabbed my stuff and headed to the race. It took a couple of minutes to find some parking, but I didn’t have to walk to far. I was able to hit up the port-a-potties on the way in to transition, and then started getting setup. It seems like I got stuff setup quicker then my last race, which I guess is a good thing. I remember the announcer saying that they were going to do the National Anthem, and the pre-race meeting in about 5 minutes, so I went to go use the bathroom (again). When I stepped out of the port-a-potty I heard the announcer say they were closing transition in 5 minutes. That was the first mention I heard about closing transition, but I had plenty of time to grab my wetsuit, cap and goggles and start the walk to the start area.

The swim course was point to point, and we had to walk close to a mile down the beach to get to the swim area. I put my wetsuit on just outside of transition, and made the long trek down the beach. Some people were smart and started jumping in the water when they got closer to the start area to take care of the warm-up. I haven't had too much difficulty with the swim, and only need a very short warm-up so I continued to walk along the beach. When I finally got in the water, it didn’t feel too cold, but as soon as I put my head in, I thought I was going to die of shock. Wow! My warm-up was more for getting my face used to the water then anything else.

One interesting thing I’d like to point out, is that aside from my face in the water, I was never cold at all. I was wearing my sleeveless tri-top and shorts before the race, and obviously during the race, and was never cold, although the air temperature was no more then 65 (until the sun came out on the run). Usually I’m looking to wear long sleeves on the bike at 65.

Swim

I was in the 3rd wave to start, 6 minutes behind the first wave. The announcer gave us a good countdown, and then we were off into the water, as this was a beach start. I actually put forth a little bit of effort to run into and thru the water. I did a couple of really lame dives to get me going, and then started swimming. As with my last race, it took me about 200 meters to get my rhythm (so maybe I do need a warm-up). This time however, things didn’t feel as crowded for some reason. I felt like I was wandering a bit on the swim course, but reviewing my GPS data showed I had a fairly decent track.

The swim only turned out to be .99 miles according to my GPS, which is disappointing. I guess they moved the buoys in closer to shore which cut out the distance you used to have to swim to get out to, and back from the buoy line. We speculated this was because of the drowning at another triathlon the weekend before. So I swam the .99 miles in 24:11, which I am happy with, and would have put me at 29 minutes for 1.2 miles, as I know I could have kept my same pace. If anything, I could have went a little faster I think, but it’s so hard to know how fast you are going. I even had the speed alerts programmed into my GPS, but it’s still a rather broad indication of how you are doing. I think I will up the speed alert from 2.4 to 2.5 mph for the next race.

T1

So if you read my last race report, you will know that I lost a good two minutes to most everyone else in T1. I guess I didn’t practice enough, because I still took over 4 minutes in T1, but at least I wasn’t as alone this time. At least as an age-grouper in a half iron man, an extra two minutes in T1 isn’t the end of the world. I still had the light headedness out of the swim as I did last time, so that didn’t help. I think I got my wetsuit off faster, but I could still do better. I decided to ride barefoot, but took too much time drying my feet off I think. I also walked most of the way to the mount line, as I was putting on my gloves. I need to remember to worry about the gloves after I get going.

Bike

My plan for the bike, which I decided as I was heading out of transition, was to take it easy for the first half, and try for a negative split. I rode the course the week before, and found it rather flat and boring. I had difficulty staying focused during the first half, which is why I decided to start out slow and then be able to look forward to a challenging ride back. I flipped the switch around mile 25, so a little earlier then expected, but I felt like people from the later waves were catching up to me too much, or allot of other people had the same strategy as me.

Things were going well, until about mile 35, when I was swallowed up by the peloton. I guess with the Tour de France going on, people wanted to get into the sprit of things, even though drafting is illegal. I made an attempt to pass the pack two to three times, as it would always slow down going up the “hills”, but was eventually passed up again after the hill. One the one hand it was satisfying to out climb (I use that term very loosely, as there were no real hills on that course), on the other hand, I had to spend too much energy trying to get around 30-40 riders.

I finally decided to just let the group go by and slow up for a bit. With about 5 miles to go, one of the Marshalls finally rode by and we all pointed up ahead to the group. They went up there, and were riding along side for awhile, but I don’t know what became of it. I do know there were about 130 penalties (10% of the racers) given out, and quite a few for drafting.

I finished the bike in 2:27, which was a couple of minutes faster then the 2:30 I was hoping for. I had rented a pair of Bontrager Aeolus 6.5’s, and also purchase an aero helmet for this race. I think these helped me, but it’s hard to say how much. Unfortunately, the wattage reported on my power meter seems allot lower then it should be, so it’s hard to get a feeling for how well I truly did on the bike.

T2 + Run

After my surprising well run at my last race, I was looking forward to having another successful run. Had the run only been 6 miles, I would have had a really good run, but alas, it was 13.1, and I did not do so well. The run was a two lap out and back, with two good sized hills at the start of each lap. I came off the bike and had an ok, but not stellar T2 (I don’t think I like running in my biking shoes). I had to go to the bathroom really bad, but the port-a-potties were not placed between transition and the run course. Thankfully I had found the bathroom’s located in the beach concession stand the week before, so I deviated from the run course slightly to use the facilities, and I was not the only one.

I went out strong and hard on the first lap, and that was my mistake. I had gotten some notion in my head that I could run 7:30 miles, and I can, just not for 13.1 miles after a bike ride. I think my average pace was actually around 7:45 for the first lap, but I had already started to feel fatigued on mile 5. Thru the turn-around I went, opting to skip the bathroom this time, which turned out to be a big mistake. By the time I was coming up on mile 7, I had re-adjusted my pace alert to 8:00, and by mile 8, I didn’t care about the pace alert anymore. I think my pace dropped as slow as 10:00 at one point, and ended up with an average pace of 8:20. Usually I try to sprint to the finish, but I just couldn’t.

Post Race

Figures, as soon as I was done, and got the timing chip off, the severe pain from having to go the bathroom was gone, but I still made the bathroom my first stop. The sun had come out for a bit on the run, but then dark clouds started moving in, and the wind was picking up, so I went back to transition to grab my long sleeve jacket. I then went in search of some food, and found a much better menu then what was at my last race. This time around they had P&B and BBQ sandwiches, fruit, cookies, and soda. P&B never tasted so good before, and I’m usually not a big fan of BBQ, but it too tasted quite well. After getting some food, I headed back to transition to pack up. The new transition bag worked great and held all my gear and my still wet wetsuit.

I would like to thank my Mom, Aunt Suzy, Aunt Janet and Uncle Kevin for coming out and cheering me on.

Final Results

Overall Place: 256/1206 21.2%
Age Group (M30-34): 39/101 38.6%
Swim 26:04 (216) 17.9%
T1 4:15  
Bike 2:27:24 (172) 14.3%
T2 2:17  
Run 1:49:02 (398) 33%


What's Next?

My next race is the Pigman 1/2 Ironman down in Iowa in August. I have about 4 weeks of training (including a bit of tapering the week before), and plan to focus my efforts on my running. I know I can’t start out at a 7:30 pace, but would like to some day, so I need to start training for it. Next race I plan to start out at a 8:00 pace, and then pick up the pace in the 2nd half if I am still feeling good. I’d like to shoot for 4:45 (with an actual 1.2 mile swim), but it will be close. I know Pigman has a bit more climbing then Racine, and I figure I’m due for a hot day in August. If not 4:45, at least do better in my overall placing then I did in Racine.

I still need to work a bit on my transitions, but it’s hard to simulate what it’s like on race day. However, this year was my practice year anyway, so getting real experience doing the transitions on race day is part of what this year was about.

I tried out a new nutrition plan for this race, opting for about 900 calories from a mix of Gatorade (150 calories) and Carbo-Pro in 24oz of water. This worked well from an energy standpoint, but I still felt some discomfort in my stomach. I think it was because it was so cool out, that I didn’t drink enough plain water. Although during this past winter, I’d down a 32oz Gatorade without any problems at all while working out. I like the form factor of the Cliff Shot Blocks, but I think it’s too much sugar. I may try to make a paste out of the Carbo-Pro to cut down on the amount of liquid I take in as part of my fuel.

Monday, July 27, 2009 3:03:44 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Fitness
# Thursday, July 23, 2009

I came across a blog post yesterday that showed how you can debug SMTP in .Net without having an SMTP and receiving mail server setup. As long as you are using the System.Net.Mail.SmtpClient object, you do not have to change any code at all. All you need to do is add the following to the app/web config file.

<system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\inetpub\EmailDebug" />
      </smtp>
    </mailSettings>
  </system.net>

You need to make sure the the directory you specify is setup with write permissions for the account your application is running under (i.e. Network Service).

I would like to point out, that if you are following good design patterns and practices, that this would only be used for an integration test, not a unit test. In my situation, testing was not a consideration, so I’m forced to use this to “unit test”.

Thursday, July 23, 2009 9:25:53 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Thursday, July 02, 2009

On Sunday June 14th,  I competed in my first triathlon, an Olympic distance event.  The 2009 Capitol View Triathlon and was held in and around Governor Nelson State Park just north of Madison. It was a perfect day for the event, although the temperature started creeping up towards the end. The event is put on by my friends at Endurance House, a great local tri store in Madison.

Packet Pickup

The packet pickup was held at the Hilton Garden View hotel on Madison’s west side. I showed up close to the end of the pickup time, and there were not too many people there. We had to fill out a USAT release form, which seemed kind of weird, because it was the single day event form, and I’m already a USAT annual member. Speaking of being a USAT member, I was never asked for my USAT membership card, even though it meant I had paid less for the entry fee.

There were some vendors at the packet pickup, but I was in a hurry and didn’t have time to check out the merchandise. Besides, I’ve spent way to much this season, even without buying a bike.

Pre-Race Thoughts

My goal entering the day was a finishing time of 2:40, with a stretch goal of 2:30 and a top 3 finish in my age group (based on last years results). For the stretch goal, I was hoping for a 25 minute swim, 1 hour 10 minute bike and a 50 minute run with 5 minutes worth of transitions.

Coming into the event, I had two concerns (I guess I should have had three), the open water swim, and the run. I managed to get in two open water practice swims, so I wasn’t coming in completely green. However I expected there to be some differences between swimming by yourself, and swimming with a large group of people.

The run was took place on the trails in the park, which are quite hilly in places. Based on some training I did leading up to the event, I noticed I lost about .5 mph when running off road, and I was afraid I hadn’t worked in enough hills.

Pre-Race Setup

I woke up at 5:30am and was on the way to the park by 5:50am, snacking on a cliff bar. I was extremely fortunate in that my parents live only 10 minutes away from the park. By the time we arrived at the park at 6am, people were already parking on the street, so I did as well. This resulted in about a 10 minute walk from the car to the transition area.

By the time I got to my transition spot, it was about 6:15, and there was a pre-race meeting in 30 minutes, so I didn’t have much time to set up, let alone do any type of warm-up (not that I was planning too anyway). I think I did an OK job setting up my transition area, but as you will read through-out the rest of the post, everything about my transitions needs improvement.

I got my body marking taken care of pretty easily, as a volunteer was roaming the transition area with a marker. There was nothing special about the marking, so I might just bring the same kind of marker with just in case things are getting tight. I made my way down to get my timing chip, and I should have brought my wetsuit with me, as after I was done using the port-a-potty, I had to get back to my transition spot, put my wetsuit and and make it all the way down to the beach.

By the time I got to the beach, the pre-race meeting was getting underway. There was nothing significant said during the meeting, except that the start was being delayed by 10 minutes because the support boats had not arrived yet. This did allow me some time to get in a little bit of a warm-up swim at least.

Swim

I lined up in the front of the group for the swim, but we were so spread out that there were maybe only 1-2 people directly behind me. I didn’t feel too pressured by other swimmers at the start, which was probably due to how far out we were spread, and the fact that I wasn’t trying to swim a tight circuit.

For the first 400 or so meters, I felt very out of place and poor form. My nerves finally settled down enough for me to remember what a good form felt like, and I was able to get into a comfortable rhythm for the rest of the swim. I stayed pretty much on the outside edge of the swim course, which caused me to swim further, but I had to deal with less people. I am hoping to be a little more aggressive with my positioning at my next event.

Coming out of the swim, I felt light headed and a little dizzy, which I had experienced on both my previous open water swims. I think it was a combination of the way I breath, and the cold water on the face.

I did perform my good deed for the day. On the way out of the swim, another racer ran up to me and asked for help unzipping his wetsuit. He had gotten in the zipper stuck in the flap that goes under the zipper. I’m surprised I was able to fix the zipper, while sloshing my way out of the water while being dizzy.

T1

I didn’t realize how bad my T1 was, until after I got home and looked at all of the results. I think I was 269th out of 277 racers on the T1 time….oops. The dizziness after the swim wasn’t a good start, and apparently I have really sensitive feet, because running barefoot in the parking lot was too painful, and I had to walk.

My transition area was at the far end from the swim, so I had a nice leisurely walk (I was in a race right?) to my bike. I feel I did a pretty good job setting up my transition area, so that wasn’t an issue, I just wasn’t in a hurry for some reason. I was overly paranoid about ruining my wetsuit, so I took my time getting it off. Next, I realized that my timing chip was so low on my leg it would cause problems with my shoes, so I had to take that off and re-adjust. Finally, I took way too much time drying my feet and putting socks on.

Bike

I really like biking, and like to think of the bike as my strength. I had previously biked the race course to get a feel for it, and I think this worked to my advantage. It allowed me to time a couple of my passes before and during some climbs.

After that not so stellar T1, I was able to make up quite a bit of time. I only remember being passed by 2-3 people, and was 49th overall on the bike. The only thing I can think of to improve upon (outside my normal training), is to be a little more aggressive. I need to use the passing rules to my advantage, in that once I get by someone, they have to drop back, which would allow me a few seconds of recovery before resuming my pre-pass pace.

T2

T2 was better then T1, but there is still room for improvement. Since I will be going sockless for the bike, I need to consider if I will put socks on for the run. Since my next run is twice as long, I think I’ll have to. I tried running without socks, and it wasn’t very comfortable. I just hope I don’t blow the time savings from T1 in T2 with the socks.

Run

The run was surprisingly good for me, and I beat my goal time by almost 3 minutes. I still can’t believe I ran close to 7:30 miles on trails. So I guess I’ll try to keep things the same for the run. I could probably use a little practice in drinking from cups while on the run.

After Race

I didn’t stick around long after the race. I took liberal advantage of the free Gatorade to rehydrate myself, but the greasy thin crust pizza did not look all that appealing. I like how you were able to get a print out with your results right away. Next year I plan on staying longer, as I’ll need to be present to pick up my age-group award ;)

Room for Improvement

T1 obviously needs some work, but it should be something I can take care of with a little bit of practice. I think just having one race under my belt will also help tremendously. I now know that my wetsuit is pretty durable, so I can get that thing off faster and not worry. I’ve been riding without socks, so I can cut that out and just try to dry my feet the best I can while putting my helmet on. I’ll also be attaching my gloves to my bike, and maybe even my sunglasses and worry about getting those on after I’m on the bike.

Results

  • Total Participants: 17 Elite, 22 Collegiate, 238 Age Groupers = 277
  • Age Group Ranking: 4
  • Overall Age Group Ranking: 25
  • Overall Ranking 40
  Time Overall Place Event Place
Swim 27:39.7 54 54
T1 4:37.3 117 269
Bike 1:09:56.5 49 33
T2 1:32.8 ?? 100
Run 47:05.8 40 38
Overall 2:30:52.1    

The overall place and event place include the relay results as well. However I do not consider those who participated in the relay to be in the same event as myself, and USAT rules state that Age Groupers have to factor in Elites, but they don’t say anything about relay teams. I tried to adjust the placements in the above table by removing any times from the relay teams that were faster then mine.

Final Thoughts

Aside from a disastrous T1, I was pretty happy with everything else. I feel like I stayed well hydrated on the run (pretty easy to do so on the bike), although for a half-ironman, and in warmer weather I will need more fluids. The only other thing I can do is maybe be a very tiny bit more aggressive on the bike. I held back from passing a couple of times, and I was way to passive coming back into the park (trying to be a nice guy), and probably lost a minute or two.

Next up

My next race is the Spirit of Race half iron man distance event on July 19th. This gives me 4 weeks to ramp up to the half iron distances, and fix that embarrassing T1 time. As of right now, I’m looking to do the event in 5 hours or better.

Thursday, July 02, 2009 3:29:20 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Sunday, June 07, 2009

I’ve recently decided to wrap up my previous at home project and start a new project code named WheelJack. I will be posting sometime in the future what WheelJack actually is, but for now you’ll just have to guess based on what I’m writing about.

I will be using Team Foundation Server to manage the project, source code, work items, builds, etc. While we have TFS where I work, we do not utilize all of it’s functionality, and part of this new project is an attempt to better understand what TFS can bring to the table.

I will have to admit that it’s a complete overkill for a single developer scenario, and I face a very real risk of loosing precious time dealing with TFS, but in the end I think it’s worth it. If it becomes to much of a burden, I can always switch over to subversion and re-task the SharePoint site with project management.

Before I sit down and start writing code, I need to setup a new team project, determine my branching strategy, and get Team Build running for nightly and continuous integration builds. For this project I will be using the Scrum Template for Team System created by Conchango.

Detailed instructions for installing a new template into TFS and creating a new Team project are outside the scope of this post. Provided that you have full administrative rights to the TFS box, the MSI installer does all the heavy lifting, and creating a new project is a 5 step wizard process.

With my new project created I can begin adding work items to the product backlog, define sprints, and areas. I’ve also created a Wiki on the project SharePoint site to various information, including feature description, architecture, design and implementation details. The wiki is a great tool to use when working on a project because it is so easy to create content and organize content.

With all of that out of the way for now, I can move onto creating my source tree, which involves the selection of a branching strategy. The branching strategy used for WheelJack is the Single Team Branching Strategy as defined in TFS Branching Guide version 2.0.

Single Team Branching Strategy

The single team branching strategy requires 3 branches, MAIN, DEV and RELEASE, where DEV and RELEASE are branched from MAIN. While I say 3, there will in fact be more then 3 actual branches. Whenever a new release is created, it gets it’s own branch. This strategy also allows for concurrent DEV branches.

Working in DEV

After each successful nightly build, code should be merged from MAIN to DEV. In this project, with only one dev branch, and only one developer, there will usually be nothing to merge. The following situations are examples of when there will actually be code in MAIN that needs to be merged to DEV.

  • Once we create a release branch, if a show stopping bug is discovered and fixed in a release  branch, that change is merged to MAIN, and then merged from MAIN to all dev branches.
  • If we have multiple dev branches, changes in one DEV branch could be merged to MAIN, and then from MAIN to all other dev branches.

Key features of working in DEV (taken from TFS Branching Guide)

  • Focus on wide, flat branches to enable steady code flow to MAIN and then back to peer DEV branches
  • Work in DEV branches can be segregated by feature, organization, or temporary collaboration.
  • Each DEV branch should be a full branch of MAIN.
  • DEV branches should build and run Build Verification Tests (BVT’s) the same way as MAIN.
  • Forward Integrate (FI) with each successful build of MAIN
  • Reverse Integrate (RI) based on some objective team criteria (e.g. internal quality gates, end of sprint, etc.).

Working in MAIN

Aside from the initial solution and build creation, no work should be done in Main.

Working in a Release Branch

Work in production should be limited to show stopping bugs. Changes should be merged into Main once completed. The following list was taken from the branching guide.

 

Key features of working with Release Branches (taken from TFS Branching Guide)

  • Each RELEASE is a child branch of MAIN.
  • Your major product releases from the RELEASE branch and then RELEASE branch access permissions are set to read only.
  • Changes from the RELEASE branch RI to main.  This merge is one way.  Once the release branch is created MAIN may be taking changes for next version work not approved for the release branch 
  • Duplicate RELEASE branch plan for subsequent major releases. This means there will be one branch per major release.

Source Code Repository Directory Structure

  • WheelJack$
    • DEV
      • 1.0 (Version or Feature)
        • Identical to Main
      • 1.1 (Version or Feature)
        • Identical to Main
    • MAIN
      • Source
        • Project1
        • Project1.Tests
        • Project2
        • Project2.Tests
        • References
      • BuildTypes
    • Releases
      • Release 1.0
        • Identical to Main
      • Release 1.1
        • Identical to Main
      • Release 2.0
        • Identical to Main
      • Release 2.1
        • Identical to Main

 

Every branch from Main contains everything that is in the Main branch, including the Source and BuildTypes folder (BuildTypes contain the Team Build files that define a build).

 

I started out by creating a new folder on my hard drive that corresponds to the root folder TFS (WheelJack$), and working my way down the hierarchy for Main, creating Source and BuildTypes folders. My project contains a server piece and a client piece, so starting with the server side, I created a folder named MessagingServer, and then created 4 projects under that folder. I also created a _Solutions folder under WheelJack which is where I store all of my Visual Studio Solution files (*.sln). The solution files are not checked into source control.

 

Below you can see what my folder structure looks like in Windows Explorer, and in Solution Explorer.

image image

After cleaning up the project names, namespaces, and adding the correct project references, I was able to begin looking at setting up the automated builds. I’ll pick up here next time.

Sunday, June 07, 2009 8:07:00 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Team Foundation Server | WheelJack
# Sunday, May 31, 2009

On Saturday May 30th I attended the first ever Chicago Code Camp. Thankfully it wasn’t actually in Chicago, but closer to Wisconsin which made the drive bearable. I rode down with Steve (thanks for driving) and I-Lin, and met up with Lance down there. Overall, the event was a great success I think, and it’s something we’d like to put on in Madison sometime in the near future.

Session #1 – Introduction to AOP with Post Sharp by Michael Hall

This was a good introduction to Aspect Orientated Programming (AOP) using Post Sharp (.Net Environment). I’ve looked into Post Sharp before when it first came out, but it looks like it has come a long way in terms of stability and features.

AOP involves moving code which implements non-functional requirements such as logging, security, transaction management, into Aspects which can be then applied across your application. Another term for non-functional requirements would be cross cutting concerns. An aspect can be though of as a class, and is made up of advice, or methods.

A common example used when describing AOP is the cross cutting concern or non-functional requirement of tracing. Typically, in each class where you require tracing, you will create a static read-only variable for your tracing object, and then in each method, you will call Trace.Write(). With AOP, you can apply an attribute to the class to perform tracing for all methods, or on specific methods. When the method is invoked, the tracing code is executed, either before and/or after the method body depending on how the aspect is coded. The advantage in this scenario is that you do not have to declare that tracing variable or write the code to write the trace statement every time. This way if you need to change the way the tracing works, you only have to do it in one location.

Post Sharp provide a framework for building and applying the aspects. The aspects are applied at compile time by injecting code into the compiled MSIL code. Aspects are created as attributes by inheriting from several Post Sharp base classes, which include:

  • OnMethodBoundaryAspect: Used with code you own. Allows for code to be executed before and after the method body.
  • OnMethodInvocationAspect: Used with code you do not own, allows for code to be executed before method.
  • OnExceptionAspect: Code to be executed if an exception occurs.
  • OnFieldAccessAspect: Code to be executed when a field is accessed, providing for property getter/setting like functionality on fields.
  • CompositionAspect: Change code at compile time. For example, you can force a type to implement a specific interface.

Out of the box, Post Sharp gives you an incredible amount of functionality with those base classes, but you can add new custom aspects if needed. Normally Post Sharp needs to be installed with the MSI installer since it is integrating with Visual Studio. However, instructions are available for an XCopy deployment.

Session #2 – Guarding your code with Code Contracts by Derik Whittaker

Code contracts is a project from Microsoft Research which is being integrated into VS2010, and is available in VS2010 Beta I, or as a download for VS2008. Code Contracts are a way to define static assertions at design time, to be validated at compile and run time.

You probably have written a “code contract before”, but have never realized it. A simple example is where you check to see if an object is null at the beginning of a method, and if it is, you throw an ArgumentNullExpcetion. The Microsoft version of Code Contracts replaces the If Then Throw convention with Contracts.Assert(boolean expression).

So why is the Microsoft Solution better? The Microsoft solution integrates directly into Visual Studio giving you support for Static Analysis at design time. This means that if you call a method with a Contract.Assert(paramter != null) and pass in null, you will get an error at compile time, as well as a warning in the form of a squiggly line under the method call at design time. Automatic testing tools like Pex can take advantage of the code contracts as well.

The real power of Code Contracts can be seen when you look at some of the advanced contracts offered. For example, you can validate that a return variable is not null, as well as validate a condition every time a method is called using the Invariant contract.

Run time errors are displayed using Debug.Assert behind the scenes. This is automatically disabled in the build type is set to release. You can also handle the debug assertion yourself by implementing an failed contract event handler.

Session #3 – Fluent NHibernate by Hudson Akridge

This was an excellent session and probably my favorite of the conference. Hudson is a member of the Fluent NHibernate team, so he obviously is an authority on the topic, and also has a deep passion for Fluent NHibernate that is hard to reproduce. Hudson had all of his demos compiled and running ahead of time. He simply created new projects and used printed copies of the source to type from. This saved a tremendous amount of time. When time did start to run out, Hudson simply switched over to his already completed projects to finish things up. Memo to presenters, follow this approach!

The Fluent NHibernate (FNH) wiki, as well as the project members blogs provide an excellent amount of documentation, that I simply can not duplicate in this blog post, so be sure to check out those resources.

FNH is built on top of NHibernate, and it’s purpose is to replace the NHibernate Mapping Files (HBM) with a strongly typed fluent interface, with the goal of making the use of NHibernate easier, while producing more maintainable code. It succeeds on both fronts.

FNH provides two mapping options, AutoMapper, and Fluent, both of which can be used at the same time. AutoMapper uses a convention based approach where Property and Class names map to tables in the database. This is great for simple domains and green field projects with simpler database schema requirements. The fluent interface provides for a much more granular approach to mapping, and currently supports most of the functionality provided by HBM files (most people will not know that anything is missing). The fluent interface allows you define conventions which allow you to reduce repetive mappings. For example, if all of your entities have an integer based Id field, you can define that, saving yourself from having to write the mapping code over and over.

FNH does have some limitations, such as, all properties must be public. Obviously there are some situations where this is not desirable, so you could switch to HBM files, or utilize on of three work-arounds for fluent. The first two involve nesting code at some level, while the 3rd involves the use of strings to identify the non-public field names. While you loose the strong typing and compile time checking, I think I like the string option the best.

Two general tips I learned during the session, was to always make your public properties virtual so that NHibernate’s default behavior of lazy loading will work. Hudson made the comment that you should not try to outsmart NHibernate’s lazy load mechanism. The only time you should consider eager load is if you have to detach your object from the NHibernate session. The other tip was the feature that allows you to generate a complete database schema from the NHibernate mappings. From comments I heard in the crowd, the schema generation is very impressive compared to other ORMs.

Session #4 – Mass Transit by Dru Sellers

Mass Transit is an Enterprise Service Bus (ESB) written in .Net 3.5 and is designed around simplicity and speed. I had a general idea of what Mass Transit was going into this presentation, and was hoping I would learn that it would be directly applicable to a project at work. However, it’s a little too much functionality for what we need, and that’s not a bad thing, as we could probably make use of it in the future.

While I have no immediate need for an ESB at work, I was very impressed with the .Net 3.5 syntax the project uses to handle subscriptions. I’m currently starting a prototype project that could make use of an in memory service bus, and I think I will be reviewing the Mass Transit source to see what I can borrow.

Coming from a BizTalk background, a lot of the features and functionality was comparable. However, whereas BizTalk costs money, Mass Transit is free, open source, and would probably meet the needs of most organizations. Both of the authors (Dru, the presenter is one of them) use Mass Transit daily in their jobs in the banking industry.

Session #5 – Solid WPF by Michael Eaton

This presentation could have been titled WPF and the MVVM pattern. Not that Solid WPF is a bad name, but for those of you at home, it was a talk on MVVM with some YAGNI thrown in for good measure.

This is not my first MVVM presentation, and it probably won’t be the last. Unfortunately I’m still struggling to fully understand the pattern, which is partly due to my lack of experience with WPF (which I need to remedy soon).

However, the approach that Michael took in presenting MVVM was different, in that he started with a WPF app coded using just the code behind, then did a copy/paste to a new project and tried a MVC pattern, and then finally worked in MVVM. Seeing the transformation of the application from the first to the third project did help solidify some of the MVVM concepts.   

Sunday, May 31, 2009 4:30:49 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Programming
# Thursday, May 21, 2009

Some recent events have led me to do some experimenting with Windows Embedded Standard, or WES. This is an upgraded version of Windows XP embedded. WES adds support for .Net 3.5 and Software Update Services, which are the top two new features that caught my eye. One of the nice things of WES over say, WinCE, is that you have a much richer development ecosystem to work with. Everything from the Full .Net Framework, WPF, WCF, to a huge library of open source tools and utilities, and not to mention driver support.

I’ve done some WinCE development in the past, and one of the best tools you can have, is the WinCE emulator. So when it came to WES, I wanted something where I could test stuff out without needing any hardware. The following walk illustrates what is needed to get a basic (and I do mean basic) WES image created and running in a Hyper-V vitalization environment. The following instructions were created were created from with help of the the Windows Embedded Standard (WES) help files, and a video tutorial by SJJ Embedded Micro Solutions.

Each WES image must include 7 Core Components.

  • Computer Componet/HAL
  • Shell Component
  • Language Component
  • NT Loader Component
  • File System and format components
  • Logon Component

I am going to select two macro components (macro components are components that are only made up of other components) in order to get those 7 core components. One of the macro components is provided for us, the other is one that we will create in order to get a HAL for a Hyper-V based VM.

  1. Installed Windows Embedded Standard Trial edition on a Windows XP Pro SP3 Virtual Machine in Hyper-V
  2. Navigate to C:\Program Files\Windows Embedded\utilities and run Tap.exe as an administrator. This creates a devices.pmq file in the same directory as the Tap program
  3. Open Component Designer and from the File menu, choose Import. Select the .pmq file you created in step 2, then click start.
  4. After the import is complete, click Save from the file menu to save the .sld file
  5. From the tools menu, choose component database manager
  6. On the database tab, click import and browse to your .sld file created in step 4 and then import.
  7. Close Component Designer and component database manager
  8. Open target designer and create a new target named HyperV_Test (or whatever you want to name it)
  9. Your new component should be at the bottom of the components tree on the left hand side of the IDE, double click it to add it to your target
  10. Under Software\Test & Development, double click the Runtime Quick Start Helper marco. This adds the explorer shell, FAT, NTFS and a few other essentials
  11. Go to the Configuration menu option and click check dependencies. This will add additional components, such as all those required by the Component we created from the .pmq file.
  12. From the tools menu, click Build. According to the video by SJJ, you must select release, but I think they were using the previous version of Target Designer. I only tried release. Also, you will want to specify the exact destination that you want the “image” to be created. Target Designer will delete everything in the destination folder. I decided to use a folder structure like /WESBuilds/HyperVTest/
  13. Copy the resulting image to a bootable partition. I created a new VHD file and attached it to another VM running XP. From within the running VM, I used Disk Management to partition, format and mark the partition as active. Finally I copied my image files over to the root of the new partition.
  14. Attach VHD to a new VM and boot. The first time an image is booted, the First Boot Agent (FBA) runs and completes the creation of the image.

So what did I end up with? Well, I had a WES image running in Hyper-V that used 210MB of disk space. This is a very, very basic image. The shell has an empty start menu, there is no logon, no command prompt, no networking, pretty much the bare minimum. So while this would be a good start for a final production build depending on requirements, its not very functional for development. I hope to be able to expand on this image and add the following:

  • Hyper-V extensions?
  • .Net Framework 3.5 SP1?
  • Networking and Firewall?

One question I have is, if you leave something out of an image, is there anyway to add it at a later time? For example, if you have no requirements for a web browser, and a media player initially, but need to add support in the future, what is the best way to implement?

Lot’s of potential with WES, and I’m looking forward to learning more about it.

Thursday, May 21, 2009 10:00:00 AM (GMT Daylight Time, UTC+01:00)  #    Comments [2] -
Technology | Virtualization
# Wednesday, May 20, 2009

Below is a quick overview from the TechEd 2009 Keynote. It was focused on the IT side of things (vs. the developer side).

  • Group Policy settings for BitLocker to Go. One option will dis-allow writing to a removable drive if BitLockerToGo is not enabled for that drive.
  • AppLocker
    • Specify allow or disallow by publisher
    • Use rules like version 1.0 or higher from Publisher X and Program Y. This allows you to allow a specific application to run, but not have to update the rule when a new version comes out (like you did in the previous version).
  • Problem Steps Recorder
    • End-User can record problems as they re-produce them. Creates a zip file that contains a compiled html file and a series of images.
  • PowerShell V2 included in Windows 7.
    • PS v2 can target remote computers.
    • Also looks like it comes with a IDE for power shell.
  • Enterprise Desktop Vitalization
    • Seamless virtualization experience for end users. They really don’t even know stuff is virtualized, aside from possible the window chrome looking different, and a red outline around the window
    • VMs can be configure to expire
    • Restrict VMs such that data can not be copied off of them
  • Office 2010 preview released in July
  • Server 2008 R2 and Windows 7
    • Server 2008 R2 is 64bit only
    • Server 2008 R2 and Win7 tracking for holiday 09 release
    • Mount and interact with VHD files in Win7 and R2, boot from VHD, and patch VHD’s while they are offline.
    • New Active Directory Undelete feature
  • Iain McDonald – Server Manager from MS
    • Option to “View Script” in the Management GUI’s and see the power shell script that is being executed. Allows you to quickly learn how to write scripts for management.
    • Says that most people who have Live Migration (VMWare) don’t use the automated migration, but manually move stuff around.
    • Clustered Hyper-V in R2 will support migration between physical hosts with different specs, processors, etc.
    • Remove core dispatcher lock to allow apps live SQL Server to scale very well
    • File Classification Infrastructure:
      • Find files by keywords and then set policies for those files. For example, search for all documents with company confidentiality statement and move them to a secure folder leaving a symlink in the original location, and setup links in a SharePoint site.
      • OCR technology built into R2 for searching for text in images.
      • Use FCI to do housekeeping, clean up old files, etc. For example, if a file is older than 10 years, or hasn’t been modified in the last year, delete the file. However, send a warning to the owner of the document 15 days before.
    • Exchange 2010
      • Search e-mail by keyword and apply policies
      • Outlook Web Access (OWA) is now able to view protected documents
      • OWA can search documents in e-mails
    • System Center Virtual Center
      • Shows the “View Script” feature
      • Migrated a VM running streaming video from one host to another with no noticeable disruptions.

 

From Twitter:

  • Something called “Windows Phone” announced in a Windows Mobile 6.5 session. Confirmed as a phone (hardware) created by Microsoft running Windows Mobile 6.5. Actually it sounds like it is made by HTC and looks like the touch HD. Can’t find anything online about this as of yet.
  • The ability to ignore a thread in Exchanged 2010
Wednesday, May 20, 2009 3:37:33 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Technology
Archive
<August 2009>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Copyright 2010
Adam Salvo
Sign In
Statistics
Total Posts: 251
This Year: 26
This Month: 0
This Week: 0
Comments: 34
Themes
Pick a theme:
All Content 2010, Adam Salvo
DasBlog theme 'Business' created by Christoph De Baene (delarou)