benchmark.rb
require 'json'
require 'lightstep'
require 'opentracing'
require 'net/http'
require 'pp'
require 'uri'
$base_url = "http://localhost:8000"
$test_tracer = LightStep::Tracer.new(
component_name: 'lightstep/ruby/example',
transport: LightStep::Transport::HTTPJSON.new(
host: 'localhost',
port: 8000,
encryption: LightStep::Transport::HTTPJSON::ENCRYPTION_NONE,
access_token: 'none'
)
)
$noop_tracer = OpenTracing::Tracer.new
$prime_work = 982451653
$logs_memory = ""
$logs_size_max = (1 << 20)
$nanos_per_second = 1e9
def prepare_logs()
(0..$logs_size_max-1).each do |x|
$logs_memory << ("A".ord + x%26).chr
end
end
prepare_logs()
def do_work(n)
x = $prime_work
while n != 0 do
x *= $prime_work
x %= 4294967296
n -= 1
end
return x
end
def test_body(tracer, control)
repeat = control['Repeat']
sleepnano = control['Sleep']
sleepival = control['SleepInterval']
work = control['Work']
logn = control['NumLogs']
logsz = control['BytesPerLog']
sleep_debt = 0 # Accumulated nanoseconds
sleeps = 0
answer = 0
(1..repeat).each do
span = tracer.start_span('span/test')
(1..logn).each do
span.log_event("testlog", $logs_memory[0..logsz])
end
answer += do_work(work)
span.finish()
sleep_debt += sleepnano
if sleep_debt <= sleepival
next
end
before = Time.now.to_f
sleep(sleep_debt / $nanos_per_second)
elapsed_secs = Time.now.to_f - before
elapsed = (elapsed_secs * $nanos_per_second).round
sleeps += elapsed_secs
sleep_debt -= elapsed
end
return sleeps, answer
end
def loop()
while true do
uri = URI.parse($base_url + '/control')
resp = Net::HTTP.get(uri)
control = JSON.parse(resp)
concurrent = control['Concurrent']
trace = control['Trace']
if control['Exit']
exit(0)
end
tracer = nil
if trace
tracer = $test_tracer
else
tracer = $noop_tracer
end
before = Time.now.to_f
# Note: Concurrency test not implemented
sleeps, answer = test_body(tracer, control)
after = Time.now.to_f
flush_dur = 0.0
if trace
tracer.flush()
flush_dur = Time.now.to_f - after
end
elapsed = after - before
path = sprintf('/result?timing=%f&flush=%f&s=%f&a=%s', elapsed, flush_dur, sleeps, answer)
uri = URI.parse($base_url + path)
resp = Net::HTTP.get(uri)
end
end
def backtrace_for_all_threads(signame)
File.open("/tmp/ruby_backtrace_#{Process.pid}.txt","a") do |f|
f.puts "--- got signal #{signame}, dump backtrace for all threads at #{Time.now}"
if Thread.current.respond_to?(:backtrace)
Thread.list.each do |t|
f.puts t.inspect
PP.pp(t.backtrace.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/},
f) # remove frames resulting from calling this method
end
else
PP.pp(caller.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/},
f) # remove frames resulting from calling this method
end
end
end
Signal.trap(29) do
backtrace_for_all_threads("INFO")
end
loop()