Skip to content

Commit

Permalink
Add bad cache post
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmc3 committed Jul 10, 2024
1 parent d657fc9 commit 773f00c
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions content/posts/2009-07-13-bad-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
+++
title = 'Bad cache'
date = 2009-07-13T22:00:00-04:00
+++

We had some code break down today. Here's the story.

One of the great tricks in the object oriented world is late bound variables. When it's expensive to initialize a variable, or you're not sure you're going to always use it, you don't initialize it until first use.

```vb
Public Readonly Property Something() As SomeObject
Get
If _someObject Is Nothing Then
_someObject = DoExpensiveInitialization()
End If
Return _someObject
End Get
End Property
Private _someObject As SomeObject
```

Another great trick is caching data. If you have some data that you're going to use frequently and that data doesn't change, then load it into shared memory and let all instances of your objects use it without being chatty with the database.

```vb
Private Shared s_someLookup As Dictionary(Of String, String)
Shared Sub New()
s_someLookup = GetLookup()
End Sub
```

So today, we had a whole site break down due to a slight oversight and a misapplication of these concepts. Here's a variation of the code:

```vb
Public Shared Readonly Property DataLookup() As DataSet
Get
If s_dsLookup Is Nothing Then SetLookup()
Return s_dsLookup
End Get
End Property
Private Shared s_dsLookup As DataSet

Private Shared Sub SetLookup()
Try
s_dsLookup = New DataSet() ' -- OUR LATE BOUND PROPERTY IS NOW NO LONGER NULL!!!
Dim adp As New SqlDataAdapter(CNN_STR, GetConnection()) ' -- EXCEPTION THROWN
adp.Fill(s_dsLookup)

Catch ex As Exception
' s_dsLookup = Nothing ' <<-- THE SINGLE LINE FIX

' Handle the exception, but we forget that
' we initialized s_dsLookup so now we're dead
' on every call to the DataLookup property
Handle(ex)
End Try
End Sub
```

So, code that never failed before, failed today. And I had to track it down. And tracking it down was a PAIN because:
- The breakage presented itself far away from the actual problem. Rule #1 - fail fast!
- The breakage was not reproducible in any other environment, because the failure was a fluke occurrence.
- It was a Monday, we were short staffed, overloaded with hot projects that needed to be done _yesterday_, with a bug that affects the whole company, and I am neither the author of the code nor the primary developer for the broken site. Murphy's law.
- The fix involved the inevitable discussion with management about why these sorts of things happen, and why we use these newfangled development techniques.

Doing tricks for performance purposes **always** has a tradeoff. Usually it's in the area of maintainability. Not that I'm complaining. Finding these sorts of things and fixing them makes me a better developer, and also gives me great fodder for the blog. I just wish that this stuff wouldn't inevitably happen on Mondays. Or late Friday afternoons.

0 comments on commit 773f00c

Please sign in to comment.