-
-
Save jbr/305362 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'onion' | |
Onion.new Stats, Memoizer, TimesOut do | |
config :stats => true, :timeout => 1_000, :pool_size => 20 | |
puts "Forward:" | |
transaction do | |
query "SELECT ... FROM ... FOR UPDATE ..." | |
execute "INSERT ..." | |
execute "INSERT ..." | |
end | |
reverse! | |
puts "\nBackward:" | |
transaction do | |
query "(reverse) SELECT ... FROM ... FOR UPDATE ..." | |
execute "(reverse) INSERT ..." | |
execute "(reverse) INSERT ..." | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Forward: | |
Instantiating Query Object | |
Selecting SELECT ... FROM ... FOR UPDATE ... on #<Query:0x18aa010> (connection: #<Object:0x18aa4c0>) | |
Did not timeout! Yay fast database! | |
Measured select at 1.000166 | |
Instantiating Query Object | |
Executing INSERT ... on #<Query:0x18a9a70> (connection: #<Object:0x18aa4c0>) | |
Did not timeout! Yay fast database! | |
Measured execute at 1.000148 | |
Executing INSERT ... on #<Query:0x18a9a70> (connection: #<Object:0x18aa4c0>) | |
Did not timeout! Yay fast database! | |
Measured execute at 1.000085 | |
Backward: | |
Instantiating Query Object | |
Selecting (reverse) SELECT ... FROM ... FOR UPDATE ... on #<Query:0x18a8f1c> (connection: #<Object:0x18a93cc>) | |
Measured select at 1.000116 | |
Did not timeout! Yay fast database! | |
Instantiating Query Object | |
Executing (reverse) INSERT ... on #<Query:0x18a8990> (connection: #<Object:0x18a93cc>) | |
Measured execute at 1.00013 | |
Did not timeout! Yay fast database! | |
Executing (reverse) INSERT ... on #<Query:0x18a8990> (connection: #<Object:0x18a93cc>) | |
Measured execute at 1.000094 | |
Did not timeout! Yay fast database! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Forward: | |
Instantiating Query Object | |
Selecting SELECT ... FROM ... FOR UPDATE ... on #<Object:0x11f6750> | |
Did not timeout! Yay fast database! | |
Measured select at 1.00 seconds | |
Instantiating Query Object | |
Executing INSERT ... on #<Object:0x11f6750> | |
Did not timeout! Yay fast database! | |
Measured select at 1.00 seconds | |
Executing INSERT ... on #<Object:0x11f6750> | |
Did not timeout! Yay fast database! | |
Measured select at 1.00 seconds | |
Backward: | |
Instantiating Query Object | |
Selecting SELECT ... FROM ... FOR UPDATE ... on #<Object:0x11f4ea0> | |
Measured select at 1.00 seconds | |
Did not timeout! Yay fast database! | |
Instantiating Query Object | |
Executing INSERT ... on #<Object:0x11f4ea0> | |
Measured select at 1.00 seconds | |
Did not timeout! Yay fast database! | |
Executing INSERT ... on #<Object:0x11f4ea0> | |
Measured select at 1.00 seconds | |
Did not timeout! Yay fast database! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Onion < Array | |
def initialize(*classes_or_objects, &blk) | |
@config = {} | |
super classes_or_objects.map {|q| q.new self rescue q.new rescue q} | |
instance_eval &blk | |
end | |
def wrap(method, &innermost) | |
reverse.inject(innermost) do |inner, item| | |
if item.respond_to? method | |
lambda {|*args| item.send method, *args, &inner} | |
else | |
inner | |
end | |
end | |
end | |
def construct_query(query_string, connection) | |
wrap :construct_query do | |
Query.new query_string, connection | |
end.call query_string, connection | |
end | |
def query(query_string, connection) | |
wrap :query do | |
construct_query(query_string, connection).query | |
end.call query_string | |
end | |
def execute(query_string, connection) | |
wrap :execute do | |
construct_query(query_string, connection).execute | |
end.call query_string | |
end | |
def transaction(&blk) | |
ConnectionContext.new self, connection_pool, &blk | |
end | |
def connection_pool(pool = nil) | |
@pool ||= ConnectionPool.new config[:pool_size] | |
end | |
def config(hash = nil) | |
hash ? @config.merge!(hash) : @config | |
end | |
end | |
class Query | |
def initialize(query_string, connection) | |
@query_string, @connection = query_string, connection | |
puts "Instantiating Query Object" | |
end | |
def execute | |
sleep 1 | |
puts "Executing #{@query_string} on #{self}" | |
[1,2,3] | |
end | |
def to_s() super + " (connection: #{@connection})" end | |
def query | |
sleep 1 | |
puts "Selecting #{@query_string} on #{self}" | |
1 | |
end | |
end | |
class Memoizer | |
def initialize | |
@memos = {} | |
end | |
def construct_query(query_string, connection) | |
@memos[[connection, query_string]] ||= yield query_string, connection | |
end | |
end | |
class Stats | |
def initialize(onion) @config = onion.config end | |
def respond_to?(method) @config[:stats] and super end | |
def returning(value) yield(value); value end | |
def query(query_string) | |
time = Time.now | |
returning yield(query_string) do | |
puts "Measured select at #{Time.now - time}" | |
end | |
end | |
def execute(query_string) | |
time = Time.now | |
returning yield(query_string) do | |
puts "Measured execute at #{Time.now - time}" | |
end | |
end | |
end | |
class TimesOut | |
def initialize(onion) @config = onion.config end | |
def query(query_string) | |
yield(query_string) | |
puts 'Did not timeout! Yay fast database!' | |
end | |
alias_method :execute, :query | |
end | |
class ConnectionPool | |
def initialize(num) end | |
def allocate_connection() Object.new end | |
end | |
class ConnectionContext | |
def initialize(callee, connection_pool, &blk) | |
@callee = callee | |
@connection = connection_pool.allocate_connection | |
instance_eval &blk | |
end | |
def query(string) @callee.query(string, @connection) end | |
def execute(string) @callee.execute(string, @connection) end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment