Logo
Published on

Rebuilding Redis in Go, Part 5: Optimistic Locking in an Hour

Authors
  • avatar
    Name
    Ryan Flores
    Twitter

Section 5 is done, and it took about an hour. After streams and the transactions refactor, optimistic locking felt pretty easy. WATCH, UNWATCH, and a dirty flag. That was the entire section.

Also, #678 on the CodeCrafters Go leaderboard! Still climbing.

WATCH

Optimistic locking in Redis is built on WATCH. You tell the server which keys you care about, and if any of them change before your transaction executes, the whole transaction gets discarded. Did something get flagged? If yes, then we stop the transaction and discard it.

I started with WATCH just returning OK. Then I worked out a design which included a map of watched keys to bools, false by default. Every SET checks the map, and if the key is being watched, it flips to true. Then at EXEC time, if anything in the map is true, discard the transaction and clear the map.

WATCH inside a transaction, tracking the modifications, all of it was ezzz. The design did the heavy lifting, the code just fell out of it.

UNWATCH

UNWATCH was even easier, clear the watched set. Done.

But I couldn't leave it at a bare map. I made a named type with its own Clear method:

type WatchedKeysMap map[string]bool

var WatchedKeys = make(WatchedKeysMap)

func (w WatchedKeysMap) Clear() {
	WatchedKeys = make(WatchedKeysMap)
}

Might be overboard, but I like that Clear only exists on this object, and if watched keys ever need more behavior, there's a named type waiting for it. Same instinct as the Command struct back in section 2, give the thing a name so I can add more functionality to it later.

Packages Are Not Classes

I also refactored my RESP helpers a bit. They were getting messy, and adding another helper forced the issue. Working through it reminded me that Go packages are not C# classes. No inheritance to lean on, flatter structure, and the encapsulation has to come from package boundaries and named types instead.

What's Next

I briefly considered folding this section into the next post since it's so small, but one post per section is clearer

Next up is replication, and it looks like it's a big one, also sounds a little scary. Let's see if this "ez" streak survives.