AOF: File.open("ab") + log_to_aof kwarg

Before the code: what crash-safety actually means

Your store is fast because it lives in memory. The price of that speed is that a single power cut wipes everything. This module fixes that. The trick is simple: keep a flight recorder. Every write the server accepts is appended to a file on disk. After a crash, you replay the file from the top and the server is back. That is the entire append-only log idea, used inside Redis, every SQL database, Kafka, and even git.

Write to memory, log to disk

Every write goes two places at once: the in-memory Hash for fast reads, and the log file so the Hash can be rebuilt after a crash.

Quiz: Quiz

Loading practice…

Append-only binary file. $aof_mu serialises writes across threads. log_to_aof: false during replay so we do not re-append.

05-aof-persistence/server.rb
ruby
$aof = File.open(AOF_PATH, 'ab')
$aof_mu = Mutex.new

def aof_append(args)
  return if $aof.nil?
  $aof_mu.synchronize { $aof.write(encode_array_strings(args)); $aof.flush }
end

# inside handle_args:
aof_append(args) if log_to_aof && %w[SET DEL].include?(cmd) && !reply.start_with?('-')

$aof_mu protects encode + write. Without it two threads could interleave bytes mid-frame.

log_to_aof: false is a kwarg, defaulting to true. Calling handle_args(args, log_to_aof: false) inside the replay function reuses every dispatch case without re-appending to the file.

05-aof-persistence/server.rb
ruby
def aof_replay
  return [0, 0] unless File.exist?(AOF_PATH)
  buf = File.binread(AOF_PATH)
  cur = 0
  replayed = 0
  while cur < buf.bytesize
    v, nc = parse_resp(buf, cur)
    return [replayed, buf.bytesize - cur] if v == :incomplete || v == :invalid
    cur = nc
    handle_args(args_from(v), log_to_aof: false)
    replayed += 1
  end
  [replayed, 0]
end

Replay reads the file, parses RESP frames, calls handle_args with log_to_aof: false.

$aof.flush pushes to the OS page cache. For full durability, add $aof.fsync after flush. For appendfsync everysec semantics, spawn a Thread that fsyncs once per second. The exercises walk through both.

Quiz: Quiz

Loading practice…