Don’t Dispose Your Own EF Connections

I’m working on upgrading a framework to dotnet core so I am moving from .Net 2.x conventions to netstandard 2.2. Our code was using DbContext.Database.Connection to get DB connections for custom SQL. I needed to switch to DbContext.Database.GetDbConnection(). I made the wrong assumption that GetDbConnection() was a factory method and returned a new connection every time. Therefore I made sure I was disposing of each connection. Tests immediately started failing with “System.InvalidOperationException: ‘The ConnectionString property has not been initialized.'” After investing way too much time due to the complexity of the framework and my own stubbornness, I narrowed the issue down to the following scenario:

    using (var conn = context.Database.GetDbConnection())
    {
      conn.Open();
      using (var cmd = conn.CreateCommand())
      {
        cmd.CommandText = "SELECT * FROM sys.databases";
        cmd.ExecuteNonQuery();
      }
    }

    using (var conn = context.Database.GetDbConnection())
    {
      conn.Open();
      using (var cmd = conn.CreateCommand())
      {
        cmd.CommandText = "SELECT * FROM sys.databases";
        cmd.ExecuteNonQuery();
      }
    }

The real issue is the second call to GetDbConnection(). This does not in fact return a new instance, it appears to return the previous connection and the ConnectionString property has been set to an empty string causing the exception about ConnectionString not being initialized. You can test this yourself with the following:

    var conn2 = context.Database.GetDbConnection();
    Console.WriteLine(conn2.ConnectionString);
    conn2.Dispose();
    Console.WriteLine(conn2.ConnectionString);

The fix is to simply not dispose of your connections or commands. As indicated in this issue comment, disposing of the context will dispose of any connections created using GetDbConnection(). Therefore the correct implementation of this use case is as follows:

  using (var context = new MyContext())
  {
    var conn = context.Database.GetDbConnection();
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT * FROM sys.databases";
    cmd.ExecuteNonQuery();
    conn.Close();

    var conn2 = context.Database.GetDbConnection();
    conn2.Open();
    cmd = conn2.CreateCommand();
    cmd.CommandText = "SELECT * FROM sys.databases";
    cmd.ExecuteNonQuery();
  }

Welcome to the Club, Will Smith

For the first 5.41 (give or take) miles of my last 10-mile run, I was pissed at Will Smith. That morning I watched (parts of) a video of him attempting to run a half marathon after only 3 weeks of training. Somewhere in the middle of mile 10, after over an hour and fifty minutes of running, Will started to walk. He “failed” surprising…no one (at least no one who has ever attempted a half marathon). Anyone who has ever laced up their shoes in preparation to run (or walk) a half marathon knew this only had 2 possible results:

  1. Will Smith’s workout routine included enough aerobic exercise that he could run 8-10 miles at an easy pace before he started his “3-weeks of training”. Or…
  2. He would fail.

This is why I was pissed off. I just had a hard time at getting past not only his ignorance, but also his arrogance. Even though he might not have known how much training was required, someone on his support team surely did. So, for those of us on the informer side of the distance running spectrum, this was even more of a publicity stunt than it already was for everyone else. So when Will Smith stopped running, I was happy. My first thought was, “I’m going to kick Will Smith’s ass today.”

But I got over it. You see, that is what running does. It is Jedi mind training. To be a Jedi, you must let go of your anger, and if you run long enough, you will. By the end of my run, I was no longer pissed off. I did kick his ass. My 10 miles in just under 94 minutes was at least 16 minutes faster than his and I had plenty of gas left in the tank. I also had several months of off-and-on running, probably 50-60 pounds less to carry, temperatures 10-15 degrees cooler, and most likely a much flatter course. So by the end of the run, my planned title of this post changed from “I Kicked Will Smith’s Ass” to “Welcome to the Club, Will Smith”.

Today I finally went back and watched the whole video. Full disclosure – I had previously skipped ahead to the part where he was starting the race. What I missed somewhat validated what I already knew – he hadn’t been training since his “Will Smith’s Bucket List” show had him traveling the world, eating a lot, and even drinking (something he mentioned he never did when he was building his acting career). He also mentioned he had never run 13.1 miles before and his goal pace was 2 hours and 10 minutes (just under 10 minutes a mile).

Unfortunately the rest of his training was a bit of a spectacle. He did a stress test with his cardiologist (not a bad idea before trying to run a half marathon), but then things got weird. He did some underwater training and heat and cold tolerance stuff with Laird Hamilton to apparently train his mind for the demands of the half marathon. Then he ran on some dunes. I hope that somewhere during those three weeks he also followed the type of training that running science tends to find effective.

He also had some cringe-worthy moments. There were a few times that he referred to his race as a “marathon” – something I clearly documented my distaste for already. Then when he got to the race, he jumped the barrier to start near the front of the race. In his defense, it isn’t unusual for celebrities to get a preferential starting position. However, this was still bad form. In big races, runners (often by the thousands) are arranged at the start based on their expected finishing time. In most cases, “elite” runners start in their own group before even the fastest of the rest of us riffraff. The sorting of the rest of the runners is done mostly for courtesy of runners to keep slower traffic out of their way, but it is also for safety. You don’t want someone walking and taking selfies at the start to get trampled by hundreds of runners all trying to PR.

Ultimately, it seemed to be a humbling experience for Mr. Smith. And to be fair, he didn’t “fail”. He completed the race without being picked up by the “sad wagon”. As anyone who has ever entered a race will tell you, the only measurable failure is a DNF (“did not finish”). Even this is not always a failure, because a DNF almost always means you did everything your body and mind could handle on that particular day, and THAT is an ultimate form of success. So Will’s race was a resounding success. He learned exactly what his mind and body were capable of on that day, for that race, in Havana. More importantly (in my opinion) he learned that his mind and body are capable of more. Maybe, given more training and better weather (i.e. better race selection), he finishes without breaking stride and within his pacing goal. Maybe with even more training he breaks 4 hours. Maybe he completes a full. Maybe he is competitive with other famous runners like Kevin Hart, Eddie Izzard, and Flea (to name just a few). Maybe he even qualifies for Boston.

Towards the end of the video, will said, “Ten years ago I would have been embarrassed. I would have been pissed…I’m really in a different place in my life…I don’t feel the pressure of living up to the billboard image of myself.” I’m glad that he was able to take this experience in stride. After a little research, it seems that Will has done some running in the past – just not this kind of distance. My hope is that, like so many of us, Will Smith has caught the bug. He now knows how therapeutic and downright enjoyable running longer distances can be. Perhaps more importantly, I hope Will learned how great it is to be part of the running community. As the saying goes, if you can’t say anything nice, don’t say anything at all. As a general rule, runners fall into one of those 2 modes – nice or nothing. The ones who talk are nice, friendly, positive people and the ones who don’t probably are too. This is clearly a group that Will Smith deserves to be part of so we should welcome him with open arms – even if those arms are attached to a faster-running body. 😉

Welcome to the club, Will. We are glad to have you.

Orlando Code Camp 2019 – Little Services, Big Apps

Today, I was fortunate to present on microservices at Orlando Code Camp.
I think this was my 5th straight year speaking at Code Camp, but it has definitely been long enough that I am now not sure ow long it has been. First of all, I’d like to thank the folks at the Orlando .Net Users Group for inviting me back to speak yet again. More so, I would like to thank the great group that showed up to hear my presentation, “Microservices – Little Services, Big Apps”. It was very humbling to have such a packed room and I hope everyone learned something or was at least mildly entertained. For those of you who attended, the slide deck is below. For those of you who did not attend and arrived here some other way, you can also find the slides but they will probably be far less interesting. I don’t normally record these sessions because I always try to capture a certain amount of technical Zeitgeist both from the current technology landscape and my current professional experience. Also, I feel like these community events deserve a certain amount of exclusivity for those who are able to attend. Over time, most of the content will be posted on my blog one way or another (if it hasn’t been already).

Orlando Code Camp 2019 Presentation Deck
Orlando Code Camp 2019 Presentation Deck
Keyboard keys in a pile

Tabs ARE Better Than Spaces?

For a few years, I’ve been working with a team that prefers spaces to tabs. More specifically, 2 spaces. I agree that this is a superior visual arrangement and having everyone use it benefits those of us who prefer it, those who don’t care, and will eventually bring those who don’t like it to see the light. Today, however, for reasons that will be more obvious in future posts, it occurred to me that tabs may actually be superior.

This revelation requires first admitting that this is a preference. You may code on a 32” curved 16:9 or a 20” 4:3 rotated to 3:4 portrait. You could be writing code on a flip phone for all I know. Whether you use tabs or spaces, the desired effect is the same: to provide consistent formatting to make the code easier for you to read.

This leads me to my argument for tabs: Tabs are the democratic choice. Tabs put the details of the implementation in th hands of the consumer. Most modern IDEs allow you to customize your tabs. Want tabs to be 7 spaces? Let your crazy-big-odd-numbered-tab freak flag fly! It’s much easier to customize tabs or replace them with spaces than to replace spaces with tabs. So I’m sure this debate will rage on and I will happily continue to use spaces for my code, but for you, my friend, I will give you tabs.

Tutorials Are (Often) Bad

Yes, that is a broad generalization. Yes, broad generalizations are (often) bad. Yes, I see the irony in that. However, tutorials are often bad. The good news is, this is often by design. Tutorials are intended to show you how to do something very specific. This means most basic tutorials are intended to show you how to do that specific thing as succinctly as possible. The problem (or potential problem) with this is that good code is often not particularly succinct. As I mentioned in my previous post, “optimal” code isn’t easy to design and what is “optimal” for one scenario might not be fore another. So in this post, I’m going to explore some concepts that are (often) good. Since they are often not followed in tutorials, it stands to reason that tutorials are (often) bad.

DRYness

woman drying hair too vigurously

OK, not that kind of DRY. DRY means “Don’t Repeat Yourself”. Tutorials typically keep code in as few places as possible to make it easy to follow the examples. DRY code requires separation of concerns. This means putting your code in the “right” place which means you have to have multiple places to put it. Chances are you need a more complex project/file structure than what a tutorial will show you.

Testability

test test test test test test

Unless a tutorial is demonstrating some aspect of testing, it most likely doesn’t include any tests. Because of this, the code won’t necessarily be very testable. Making your code testable requires a certain degree of DRYness since you typically want to test small units of code (“unit tests”). Most modern frameworks support features like dependency injection to improve testability, but these features are often absent from tutorials, so beware of tutorials without any tests.

Maintainability

maintenance

Testability and maintainability go hand in hand. Maintainability is definitely an art and beauty is in the eye of the beholder when it comes to what “easy to read” code looks like, but there are some good rules of thumb:

  1. Keep functions short enough to read on the screen.
  2. Use descriptive names for functions that follow the law of least astonishment
  3. Avoid unnecessarily concise notations
  4. Use consistent formatting and spacing

Tutorials probably follow number 4, might follow number 3, and very often ignore 1 and 2.

Putting it All Together

The code in tutorials is not typically well structured. Good structure means your code is DRY, testable, and easy to maintain. When following tutorials, look for opportunities to improve the structure. Develop your own toolbox of reusable code and components. You will quickly find that all projects benefit from having at least 3 components: a “core” set of code not tied to a specific implementation, at least one specific implementation, and tests. Nothing is one-size-fits-all so no one template will match every project, but it’s good to have a general approach that prepares you to write “good” code.

brain art science

The Science and Art of Code Structure

Clearly, I should have been in game development. I’ve been coding since the third grade so software was always in the cards for me. I have a degree in Mechanical Engineering so I have the physics chops to handle pretty much any kind of real-world simulation from projectile motion and particle physics to fluid dynamics and even heat transfer. My masters degree is in Industrial Engineering so I know about things like optimization and simulation that are helpful for AI (among other things). And games are fun!

What I realized recently, is that writing “good” code is an Industrial Engineering optimization problem. You see, optimization problems deal with multiple dimensions with often multiple optimal solutions. Note the use of the word “optimal” and not “best”. Optimization problems often have multiple variables and an astronomical number of potential solutions. So when you are optimizing code, what is your goal? Maximize speed of execution? Minimize size of compiled code? Minimize bandwidth used? Minimize processing power used? Minimize total operating cost? Maximize test code coverage? Why not all of them? Well…I’ll tell you why.

One of the most famous examples of an optimization problem and how mind-bogglingly many solutions they could have is the “traveling salesman problem“. The traveling salesman must visit some number of potential clients and then return home. In the simplest version, he is flying from city to city and the only concern is the order of the flights to the various airports. A much more practical and complex version is a package delivery company with a fleet of trucks needing to deliver packages over routes through a complex network of highways and city streets with variable traffic, one way streets, traffic lights, etc. Every variable multiplies the number of solutions by the number of possible options for that variable.
The number of possible solutions very quickly gets large – like more than the total number of atoms in the known universe large. What hope do we have of solving these problems? Luckily, we have pretty cool brains.

Malcolm Gladwell wrote a book titled Blink: The Power of Thinking Without Thinking. It’s a great book and I highly recommend reading it, but the gist is our brains are able to take in a vast array of information and come to a conclusion (an “optimal solution”) without consciously thinking about it. This ability to organically problem solve was also recently discovered in single cell organisms. This is why we are pretty good at coming up with decent solutions to these problems without knowing anything about linear algebra. Our brain operates on “heuristics” that our life experiences have allowed our brains accept without having to think about them. In the world of software development, the use of these heuristics are the “art” and allow us to optimize variables that are extremely more challenging and seemingly abstract such as “maximize code reuse” and “maximize maintainability” and, as I like to say, “minimize astonishment“.

Another important consideration in optimization is boundaries. For example, you may be able to purchase a certain amount of computing resources for a certain cost. Additional resources add more cost. This means that you don’t necessarily need to use an absolute minimum number of resources, you just need to make sure that the amount of resources used doesn’t trip the threshold or that if it does, you have a source of revenue to cover the added cost.

In future posts, I will dive into more detail on the day-to-day practical advise on optimizing your code, but first I wanted to take some time to lay some groundwork. In the early days of computers, you were greatly constrained by memory and processing power. You had a limited number of pixels that could be rendered on the screen in a limited number of colors. You could only store so many bytes of code. You were limited to a small number of operations the processor performed. You were limited in the language you could code in and the structure of that language. The optimization required was much more science with a small number of options for each variable. Now, the options are astronomical. What language do you use? What platforms or devices run that code? What communication channels does it leverage? How many millions of colors and pixels does it render? Sure, it is still important to minimize operating cost (storage, CPU cycles, bandwidth, etc.), but you can also get access to a significant amount of resources for little or no cost. This allows you to focus on the art – maintainability and reuse – first, and then solve the challenging scientific problems later (or not at all).

teacher and student

Eminence Imminent

After spending nearly 20 years working for a defense contractor, I joined Deloitte to focus more on software and to build that software for clients outside of the defense business. I’ve been with Deloitte for a few years now and I’m starting to take a more active role in Systems Design and Engineering leadership. This means helping with activities to establish “eminence” of our practitioners. For me, that means being more active in those activities myself…practicing what I preach…eating my own dog food…I think you get the point.

I’ve consolidated some of my old blogs here. It’s been a long time since I’ve posted anything technical, so most of that stuff did not survive the move here. However, I have some nerdy things in the works and a few decades of…wisdom?..to share. I’m looking forward to unleashing the avalanche of blog posts swirling in my head.

I’m trying to run a little more often (ok, a LOT more often) so I’ll be posting about that too. Beware, I am a running nerd so expect plenty of over-analysis while I try to regain or even surpass my fitness level of years gone by.

So for those of you who have stumbled onto my little corner of the internet, I welcome you and hope you find some knowledge, inspiration, or at least some entertainment.

treadmill

A Bad Metaphor

Most people reading this have probably heard the metaphor comparing something to a marathon as opposed to a sprint: your education is a marathon, not a sprint; your career is a marathon, not a sprint; investing is a marathon, not a sprint. At first, the meaning seems obvious. A marathon is 42,195m (26.2 miles) and sprints are 400m or less. You don’t have to be good at math to see that the marathon is more than 100 times longer. The marquis sprinting distance is 100m and is used to crown the “world’s fastest” man and woman. Both cover the distance in less than 11 seconds. Both marathon world records are over 2 hours. The Disney Marathon requires you maintain a pace of 16 minutes per mile which will get you to the finish line in a few seconds less than 7 hours. A marathon is much longer than a sprint. I get it. Or I thought I did until I finished my first marathon.

When I started training for my first 5k, I did a “couch to 5k” program. I ran several days a week running longer and longer intervals until I could run 30 minutes wihout stopping (the approximate time it takes to finish a 5k). To be ready to train for a marathon, I needed to be able to run 8-10 miles wihot stoppimg. About 6 months after that first 5k race, I ran a 15k and started training for my first marathon. My training plan lasted 16 weeks running 4 days a week and peaked at 40 weekly miles and a long run of 20 miles. The long runs took 3-4 hours (or longer). Then I ran for 4 hours and 27 minutes and had over 4,000 people finish ahead of me and many more behind me.

Between my first and second marathon, I ran four 5ks, two 15ks, and three half marathons over more than 2.5 years. I lost 15-20 pounds off of my already slight frame. My goal was to finish faster and run the full distance without stopping (I walked through the water stops during my first marathon). I added a 5th day of running to a 18 week training plan and peaked at 50 miles a week with a long run of 20 miles. This was on top of years of gradually improving fitness.

So if it isn’t obvious yet, a bigger difference between a sprint and a marathon, bigger than the  difference in distance, is the difference in preparation required. Most people can run 100m. Most of those who can’t are able to walk 100m. However, most major marathons include hundreds of people who enter and prepare only to fail to finish. This still isn’t the biggest difference.

I don’t know when it specifically occurred to me. Maybe I was on a run and saw someone pushing their belongings in a shopping cart. Maybe I had stopped at my local drug store to buy a Gatorade from someone working a second job. Eventually it occurred to me that not everyone can train for a marathon. You need time, support, health, and at least a little disposable income. If any one of these things is missing, you are going to have a hard time. Start adding them up and it quickly becomes impossible. Running a marathon requires privilege.

When I trained for my first 5k, I wore workout clothes I already owned and wore shoes I bought because they were a bargain, but I did most of my running on a treadmill in a gym. By the time I ran my second marathon, I had gone through more pairs of shoes than I could count and most set me back more than $100. I had enough of my favorite running shorts and sweat wicking shirts to run 5 days a week without having to do laundry in between. I usually had 2 pairs of shoes so one could be nice and dry while the sweat and occasional rain evaporated from the others. I had a wife and extended family to help watch the kids. I had a job that gave me the  flexibility to have time to run. I had the required privilege.

So when someone tells you something is a marathon and not a sprint, not only does it take time but it probably also takes preparation. And if it takes both, you must have the privilege to even have the opportunity to undertake something that requires time and preparation. So when someone uses this metaphor, be thankful for the marathons your life gives you the opportunity to run.

13.1 marathon is not a thing

Stop Saying “13.1 Marathon”

The latest foray into the commercialization of running is the Michelob ULTRA 13.1 Marathon Series (http://www.131marathon.com/).  I like beer. I even like Michelob. I like running. I accept that for-profit race series exist. So why should this be offensive?  Quite simply, 13.1 miles is not a “marathon”.  It is a half marathon. A marathon is 26.2 miles.
I understand other races are named by their distances. No one is confused or offended by someone saying 5k or 10k, but also no one familiar with running would call those races a “5k marathon” or “10k marathon”.
I also understand that a half Ironman is also called a 70.3 Ironman. The difference there is that “Ironman” is a trademark held by the World Triathlon  Corporation.  Other races can’t call themselves a half ironman or full ironman so they often use the distance (70.3 or 140.6) and just like we use Kleenex as a generic term, people sometimes use the term “70.3 ironman” to describe a half Ironman distance race.  However, in my experience the preference seems to be “70.3” or “half ironman”.

I tried to find an explanation for this naming convention. Wikipedia doesn’t know what a 13.1 marathon is and the first several pages of a google search all point to the Michelob race. At first I thought it was comical to see “how far is a 13.1 marathon” but then I realized I had already asked and answered that question by visiting the site above for the Michelob series.

Not surprisingly, it is 13.1 miles.

I can only assume that the goal is to make this race more approachable. Not everyone knows how far a marathon is. Most people have never run one. They know it’s a long race. They might know you get medals and other “swag” when you complete one. They might even know you aren’t required to run the whole time.  Calling a race a “13.1 marathon” might make running and racing appealing to more people which I am all for.  It still makes my skin crawl.

I’m a very typical runner in many ways. I started in 2009 and did a “couch to 5k” program pounding away on a gym treadmill wearing cotton gym shorts and heavily discounted Nike trainers that were too small. My wife and I ran our first 5k in a relatively small race but we got to wear bibs with numbers on them and had our time recorded electronically and had people we didn’t know cheering us on even though we were nowhere near the front of the pack.  I finished that race barely in the front half but I was hooked.

As for my commitment to running, I might be a little more aggressive than some. After that first 5k, we moved straight on to training for a full marathon and threw in a 15k for good measure. After my first marathon in January 2011, I focused on 5ks and half marathons for a while.  By the time I ran my second full marathon in 2013 I had moved from the middle of the pack in that first 5k to the 89th percentile in the Marine Corps Marathon.
Why am I sharing all of this information?  Am I just bragging? Maybe I am bragging a little, but that is because I have earned it. I’m not bragging about finishing ahead of about 89.4% of people who ran with me in DC. I am bragging that I ran that race 45 min and 22 sec faster than my previous race at that distance. I am bragging that I dropped my average pace per mile from 10:12 to 8:28.

You see, most of us who do go out and run every week and race often aren’t racing against each other any more than someone who just does one race to cross it off of their bucket list. We are racing against ourselves. The marathon is the “premier” distance for people who want to improve their running. It is the gold standard yardstick for measuring endurance running performance.  That’s still not why I find the term “13.1 marathon” offensive.
The real crux of my contempt is this: the body starts to “break down” after covering 20 miles. I’m not going to try explain the physiology, but I will tell you this: even now at my lowest level of fitness and training in years, I could still run 13.1 miles without stopping. It will be slow, but I could finish. I could not run 26.2.  The marathon is special. So let’s not water it down by trying to turn it into Kleenex.

horse zebra and pony

Look for Horses, Not Zebras

I have two quotes from old friends that have stuck in my head in certain situations.  The first is, “dancing is like standing still, only faster.”  As a runner, I have adapted that to, “running is like falling down, only slower.”  The second is, “when you hear hoofbeats, think of horses, not zebras.”  As a programmer, I have found there is not much better advice than this second quote.

You would think that the more experience you have, the more likely you are to look for the obvious answer.  I’ve found that the opposite is true – while you are going to make “stupid” mistakes less frequently, the majority of your mistakes are still going to be “stupid”. Unfortunately with great power comes great ego, and the most difficult bugs are caused by the occurrence of something that was “never going to happen”.  I happened to stumble through 3 of these self-induced hair-pulling-out exercises in a matter of days.  To make matters worse, I don’t really code at work anymore.  This was a hobby project that I can only work on for an hour or two each night.

First was the infinite loop (and subsequent stack overflow) – one of the few errors that can’t be captured with standard error logging techniques.  This problem only happened on the production server so instead of doing the obvious and duplicating the data down to dev so I could debug, I decided to add debug logging until I found the problem.  This was the first symptom of my bravado.  My application is a state machine “engine” that runs in a loop. As things happen and the state changes, the loop eventually completes.  I narrowed down the problem to the state where the error occurred but had trouble getting closer than that.  I was convinced that some dark magic was at play and some data anomaly so I spent a few nights adding debugging, publishing, running, repeating.

Finally, I stopped looking for zebras.  Instead of continuing to try to zero in on the line of code through trial and error addition of debug logging, I put 3 lines of code in the most obvious places the problem could occur – the 3 while loops that could get called inside my main loop. That immediately pointed me to the loop in question so then I threw an exception when a condition causing an infinite loop occurred.  It probably took me all of 5 minutes to determine the state that caused the problem.

So next I had to figure out how the code got into that state.  All of the information I needed to solve the rest of the problem, I saw within minutes – and completely ignored.  I saw that the state in question could only come from the database because the key data was never set anywhere by code.  Therefore, the code that allowed the infinite loop condition must have been in the code that loaded the data from the database.  However, rather than looking right where all indications pointed, I looked for zebras.  Since I knew how to find the problem, I could now duplicate it on my dev box and debug.  That meant I could spend time inspecting variables at breakpoints to see why the problem was happening.  After all, this infinite loop was caused by a recursive linked-list relationship – something that was “never going to happen”.  There couldn’t have been an obvious reason for something like this to happen so I had dig for a needle in the haystack instead of following the thread attached to the needle.  In spite of myself, I did eventually figure out that the problem could absolutely be solved when the data was loaded into the engine.  Technically this is after the data is extracted from the database, but the recursive situation doesn’t matter until it gets to the engine so that’s where I put the fix to truncate the recursive linked list since the duplicate reference shouldn’t have been there anyway.

Fast forward a few days.  With my problem solved, I was able to run my engine for a few days and then started to look at the output.  Then I stumbled on a new error – “An error occurred while reading from the store provider’s data reader. See the inner exception for details” and the inner exception was “Arithmetic overflow error for data type tinyint, value = 2288”.  So, the expert programmer has managed to break the Entity Framework.  Of course I checked the “obvious” problem – that my model had the wrong data type.  Then I went off the deep end.  Unfortunately, there are people who have had legitimate problems with EF or linq-to-SQL mapping parameters incorrectly (2288 was a parameter, not a database value).  I converted my linq expression into a SQL command and then realized I was once again looking for zebras.  Instead of looking at the columns in my database that would map to tinyint, I assumed the problem was in the Entity Framework – code written by Microsoft and used by thousands if not millions of people – and not in MY code.  When I stepped through my code and looked at the parameters, I noticed there was a parameter that should’t have even been there.  That was my problem – I passed the parameters into my method in the wrong order!  Instead of passing “int, null, int, true” I was passing “int, int, null, true”.  The 2nd and 3rd parameters were both nullable ints so as far as the compiler was concerned this was all good.  Unfortunately it meant it passed my very large primary key into a parameter that was expecting a much smaller value – something that should have been very obvious from the error.

This post has been sitting in draft for so long that I have now had several more “events”.  The most recent was while doing a demo on AngularJS directives with my team at work.  I was trying to illustrate scope isolation and no matter what I tried I couldn’t figure out why the attribute from the directive specified in my HTML wasn’t making its way to my link function in the directive code.  When I turned off scope isolation and pointed at the parent scope, everything worked fine.  Even my more Angular-savvy team members were stumped.  Then came the “duh” moment – I actually had 2 directives nested inside each other.  I was looking at the code in the inner directive and passing data into the outer directive.  The HTML of the inner directive wasn’t passing the value from the parent.  Yet another zebra chase.

So in conclusion, drop the attitude!  When you have problems, they are most likely the most basic and amateur issues.  Reign in those horses and let the zebras smack you in the head, don’t go looking for them.

UPDATE: 29 January 2019

I have done it again! I was working on a new framework feature and couldn’t get my test to work. I just KNEW it was a problem with the third-party software I was using. More specifically, I wasn’t sure what I was trying to do was even supported. Then somehow I managed to get everything to work directly with said software. After days of struggling, I discovered I was writing the final portion of my test immediately after testing deleting the exact thing I am trying to test. As usual, my code was doing EXACTLY what I told it to do.

On a side note, since the original post, I was introduced to the concept of rubber duck code reviews. I highly recommend this and your coworkers will thank me.