Skip to content

Instantly share code, notes, and snippets.

@kml
Last active October 13, 2015 08:33
Show Gist options
  • Select an option

  • Save kml/4368cae5de3f7384fd08 to your computer and use it in GitHub Desktop.

Select an option

Save kml/4368cae5de3f7384fd08 to your computer and use it in GitHub Desktop.
RecordPlayer

Record responses and play them from local cache.

Installation:

git clone https://gist.github.com/4368cae5de3f7384fd08.git recordplayer
mkdir ~/.recordplayer

Usage:

RECORDPLAYER_ROOT=~/.recordplayer RUBYOPT="-r /.../recordplayer/recordplayer.rb" ruby -S bundle exec ...
# encoding: utf-8
require "active_support/callbacks"
require "active_support/dependencies/autoload"
require "active_record/connection_adapters/abstract_adapter"
module ActiveRecord
module ConnectionAdapters
class AbstractAdapter
def select_all(arel, name = nil, binds = [])
sql = to_sql(arel, binds)
record_player = RecordPlayer.new("ar", "#{sql}")
unless record_player.exist?
puts "RecordPlayer[ActiveRecord]: MISS: #{sql}"
record_player.write_meta("#{sql}")
record_player.write_data(super(arel, name, binds))
end
record_player.read_data
rescue Exception => exception
warn ::Logger::Formatter.new.__send__(:msg2str, exception)
binding.pry
end
end
end
end
require "active_support/basic_object"
require "active_record"
require "arjdbc"
require "arjdbc/jdbc/adapter"
module ActiveRecord
module ConnectionAdapters
class JdbcAdapter
alias original_execute execute
def execute(sql, name = nil, binds = nil)
sql = to_sql(sql, binds)
record_player = RecordPlayer.new("ar", "#{sql}")
unless record_player.exist?
puts "RecordPlayer[ActiveRecord]: MISS: #{sql}"
record_player.write_meta("#{sql}")
record_player.write_data(original_execute(sql, name, binds))
end
record_player.read_data
rescue Exception => exception
warn ::Logger::Formatter.new.__send__(:msg2str, exception)
binding.pry
end
end
end
end
# encoding: utf-8
require "moped/cursor"
module ::Moped
class Cursor
class << self
alias :original_new :new
end
def self.new(session, query_operation)
record_player = RecordPlayer.new("moped", "#{session.inspect}||#{query_operation.inspect}")
cursor = original_new(session, query_operation)
unless record_player.exist?
puts "RecordPlayer[Moped]: MISS: #{query_operation.inspect}"
record_player.write_meta("#{session.inspect}\n\n#{query_operation.inspect}")
record_player.write_data(cursor.load_docs)
end
class << cursor
attr_accessor :cached_docs
alias load_docs cached_docs
end
cursor.cached_docs = record_player.read_data
cursor
rescue Exception => exception
warn ::Logger::Formatter.new.__send__(:msg2str, exception)
binding.pry
end
end
end
# encoding: utf-8
require "rsolr"
module ::RSolr
class Client
alias :unrecorded_execute :execute
def execute(request_context)
record_player = RecordPlayer.new("rsolr", "#{request_context[:uri]}")
unless record_player.exist?
puts "RecordPlayer[RSolr]: MISS: #{request_context.inspect}"
record_player.write_meta("#{request_context.inspect}")
record_player.write_data(unrecorded_execute(request_context))
end
record_player.read_data
rescue Exception => exception
warn ::Logger::Formatter.new.__send__(:msg2str, exception)
binding.pry
end
end
end
# encoding: utf-8
Gem::Specification.new do |spec|
spec.name = "recordplayer"
spec.version = "0.0.1.pre"
spec.platform = Gem::Platform::RUBY
spec.authors = ["Kamil Lemański"]
spec.summary = "RecordPlayer"
spec.description = "RecordPlayer"
spec.homepage = "https://gist.github.com/kml/4368cae5de3f7384fd08"
gem.files = Dir["#{File.dirname(__FILE__)}/**/*"]
spec.require_path = "."
end
# encoding: utf-8
require "bundler/setup"
require "pry"
require "digest/md5"
require "pathname"
require "logger"
# FIXME
# Gem::LoadError: You have already activated jruby-openssl 0.9.10,
# but your Gemfile requires jruby-openssl 0.9.7. Prepending `bundle exec` to your command may solve this.
gem "jruby-openssl", "0.9.7"
unless ENV["RECORDPLAYER_ROOT"]
abort "recordplayer: RECORDPLAYER_ROOT ENV variable is not set"
end
RECORDPLAYER_ROOT = Pathname.new(File.expand_path(ENV["RECORDPLAYER_ROOT"]))
unless RECORDPLAYER_ROOT.directory?
abort "recordplayer: RECORDPLAYER_ROOT #{RECORDPLAYER_ROOT} is not directory"
end
unless RECORDPLAYER_ROOT.writable?
abort "recordplayer: RECORDPLAYER_ROOT #{RECORDPLAYER_ROOT} directory is not writable"
end
puts "recordplayer: RECORDPLAYER_ROOT: #{RECORDPLAYER_ROOT}"
class RecordPlayer
attr_reader :key
def initialize(prefix, data)
@key = "rp-#{prefix}-#{Digest::MD5.hexdigest(data)}"
end
def exist?
RECORDPLAYER_ROOT.join("#{key}.marshal").exist?
end
def write_meta(meta)
File.open(RECORDPLAYER_ROOT.join("#{key}.txt"), "w") do |f|
f.write(meta)
end
end
def write_data(data)
File.open(RECORDPLAYER_ROOT.join("#{key}.marshal"), "wb") do |f|
f.write(Marshal.dump(data))
end
end
def read_data
File.open(RECORDPLAYER_ROOT.join("#{key}.marshal"), "rb") do |f|
Marshal.load(f)
end
end
end
require_relative "recordplayer-moped"
require_relative "recordplayer-rsolr"
require_relative "recordplayer-active_record"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment