The Power of Once: Basecamp's Gem for Atomic Code Execution
Once-Campfire is a small, lightweight library created by Basecamp, designed to ensure that a block of code runs only once—ever—across the entire lifespan of your application or process.
As a software engineer, this can be incredibly useful when you need to perform a one-time setup, initialization, or lazy-loading action.
Here's why Once-Campfire is a valuable tool in a software engineer's toolkit
Preventing Double Initialization
It's the primary use case. If you have a critical resource (like connecting to a database, configuring a global logger, or setting up a singleton object) that must only be initialized once, Once-Campfire guarantees this, preventing subtle and hard-to-debug bugs caused by race conditions or accidental re-initialization.
Thread Safety and Concurrency
In a multi-threaded or concurrent application (common in Ruby/Rails environments), calling a setup method from multiple threads simultaneously can be disastrous. Once-Campfire is designed to be thread-safe, ensuring that only one thread successfully executes the code block, and others wait for the result or just skip the execution if it's already done.
Lazy Loading
You can defer expensive initialization until the moment it is actually needed. The first time a piece of code calls the once method, the initialization runs. Subsequent calls instantly skip the execution, making your application start faster and consume fewer resources initially.
Once-Campfire is typically used in Ruby projects, often within the Ruby on Rails framework, as Basecamp created it for their own use.
If you're using Ruby and Bundler, add the gem to your Gemfile
# Gemfile
gem 'once-campfire'
Then, run the bundle command in your terminal
bundle install
The core of the library is the Once class. You create an instance of it, and then you call the #once method with a block of code you want to execute only one time.
# 1. Instantiate a Once object (you might put this in an application-wide class)
$GLOBAL_SETUP = Once.new
def setup_my_database
# 2. Call the #once method with the setup code block
$GLOBAL_SETUP.once do
puts "--- Running critical one-time setup! ---"
# Imagine this is an expensive, critical setup process:
# Database.connect(host: 'prod', port: 5432)
# GlobalLogger.configure(level: :info)
# The result of the block is cached and returned on subsequent calls
true
end
end
Let's look at a concrete example of lazy-loading and connecting a global service in a hypothetical Ruby class.
require 'once' # Remember to require the gem if not in Rails
class GlobalConfiguration
# Initialize the Once object. It's often helpful to keep this as an
# instance variable of the class that needs the one-time setup.
def initialize
@setup_once = Once.new
@service = nil
end
# This is the public method that ensures the service is ready.
def configure_global_service
# The block inside #once will only execute the FIRST time this method is called.
@setup_once.once do
puts "Configuring and connecting to external service..."
# This is the expensive, one-time initialization logic
@service = connect_to_external_api(ENV['API_KEY'])
puts "Service connected successfully."
# The block returns the initialized service instance
@service
end
end
# Helper method (imagine this does the heavy lifting)
private def connect_to_external_api(key)
# ... connection logic ...
return ExternalService.new(key) # A hypothetical class instance
end
end
# --- Usage Demonstration ---
config = GlobalConfiguration.new
# First call: Executes the block inside 'once'
puts "\nAttempt 1: "
service_instance = config.configure_global_service
puts "Service object ready: #{service_instance.object_id}"
# Second call: The block is completely skipped, and the cached result is returned instantly.
puts "\nAttempt 2: "
service_instance_2 = config.configure_global_service
puts "Service object ready: #{service_instance_2.object_id}"
# Third call: Also skipped, returns the same cached result.
puts "\nAttempt 3: "
service_instance_3 = config.configure_global_service
puts "Service object ready: #{service_instance_3.object_id}"
# Note: All object_ids will be identical, proving the setup ran only once.
Output
Attempt 1:
Configuring and connecting to external service...
Service connected successfully.
Service object ready: 47124357591600
Attempt 2:
Service object ready: 47124357591600
Attempt 3:
Service object ready: 47124357591600
Notice how "Configuring and connecting..." only appears once, even though configure_global_service was called three times. This is the power of Once-Campfire!