class Cassette
Represents a collection of HTTP interactions using content-addressed storage.
A cassette serves as a container for multiple class Async::HTTP::Capture::Interaction
objects, storing each
interaction as a separate JSON file in a directory. Files are named using the
content hash of the interaction, providing automatic de-duplication and
parallel-safe recording.
Definitions
attr_reader :interactions
Signature
-
attribute
Array(Interaction)
The collection of interactions.
def initialize(interactions = [])
Initialize a new cassette with the provided interactions.
Signature
-
parameter
interactions
Array(Interaction)
The interactions to include in the cassette.
Implementation
def initialize(interactions = [])
@interactions = interactions
end
def each(&block)
Iterate over each interaction in the cassette.
Signature
-
yields
{|interaction| ...}
Each interaction in the cassette.
-
parameter
interaction
Interaction
The current interaction being yielded.
-
parameter
Implementation
def each(&block)
@interactions.each(&block)
end
def self.load(directory_path)
Load a cassette from a directory of JSON interaction files.
Signature
-
parameter
directory_path
String
The path to the directory containing JSON interaction files.
-
returns
Cassette
A new cassette instance with the loaded interactions.
-
raises
JSON::ParserError
If any file contains invalid JSON.
Implementation
def self.load(directory_path)
return new([]) unless File.directory?(directory_path)
json_files = Dir.glob(File.join(directory_path, "*.json"))
interactions = json_files.map do |file_path|
data = JSON.parse(File.read(file_path), symbolize_names: true)
Interaction.new(data)
end
return self.new(interactions)
end
def save(directory_path)
Save the cassette to a directory using timestamped files. Each interaction is saved as a separate JSON file with a timestamp-based name. This approach provides parallel-safe recording.
Signature
-
parameter
directory_path
String
The path to the directory where interactions should be saved.
Implementation
def save(directory_path)
FileUtils.mkdir_p(directory_path)
@interactions.each_with_index do |interaction, index|
timestamp = Time.now.strftime("%Y%m%d-%H%M%S-%6N")
filename = "#{timestamp}-#{index}.json"
file_path = File.join(directory_path, filename)
File.write(file_path, JSON.pretty_generate(interaction.to_h))
end
end
def replay(app)
Replay all interactions against the provided application. This is useful for warming up applications by replaying recorded traffic.
Signature
-
parameter
app
#call
The application to replay interactions against.
Implementation
def replay(app)
count = @interactions.length
Console.info(self) {"Replaying #{count} interactions for warmup..."}
@interactions.each do |interaction|
Console.debug(self, "Replaying interaction:", interaction)
# Replay the interaction against the app:
if request = interaction.request
begin
response = app.call(request)
response.finish
rescue => error
Console.warn(self, "Failed to replay interaction:", error)
end
end
end
Console.info(self) {"Warmup complete."}
end