hello_world.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. MAX_PK = 10_000
  2. SEQUEL_NO_ASSOCIATIONS = true
  3. Bundler.require :default
  4. # Configure Sequel ORM (Sequel::DATABASES)
  5. Sequel.connect \
  6. '%<adapter>s://%<host>s/%<database>s?user=%<user>s&password=%<password>s' % {
  7. :adapter => RUBY_PLATFORM == 'java' ? 'jdbc:mysql' : 'mysql2',
  8. :host => ENV['DBHOST'],
  9. :database => 'hello_world',
  10. :user => 'benchmarkdbuser',
  11. :password => 'benchmarkdbpass'
  12. },
  13. :max_connections => (ENV['MAX_THREADS'] || 4).to_i,
  14. :pool_timeout => 5
  15. # Allow #to_json on models and datasets
  16. Sequel::Model.plugin :json_serializer
  17. class World < Sequel::Model(:World); end
  18. class Fortune < Sequel::Model(:Fortune)
  19. # Allow setting id to zero (0) per benchmark requirements
  20. unrestrict_primary_key
  21. end
  22. # Configure Slim templating engine
  23. Slim::Engine.set_options \
  24. :format => :html,
  25. :sort_attrs => false
  26. # Our Rack application to be executed by rackup
  27. class HelloWorld < Sinatra::Base
  28. configure do
  29. # Static file serving is ostensibly disabled in modular mode but Sinatra
  30. # still calls an expensive Proc on every request...
  31. disable :static
  32. # XSS, CSRF, IP spoofing, etc. protection are not explicitly required
  33. disable :protection
  34. # Don't add ;charset= to any content types per the benchmark requirements
  35. set :add_charset, []
  36. end
  37. helpers do
  38. # Return a random number between 1 and MAX_PK
  39. def rand1
  40. Random.rand(MAX_PK) + 1
  41. end
  42. # Return an array of `n' unique random numbers between 1 and MAX_PK
  43. def randn(n)
  44. (1..MAX_PK).to_a.shuffle!.take(n)
  45. end
  46. end
  47. after do
  48. # Add mandatory HTTP headers to every response
  49. response['Server'] ||= 'Puma'.freeze
  50. response['Date'] ||= Time.now.to_s
  51. end
  52. get '/json', :provides => :json do
  53. JSON.fast_generate :message => 'Hello, World!'.freeze
  54. end
  55. get '/plaintext', :provides => :text do
  56. 'Hello, World!'.freeze
  57. end
  58. get '/db', :provides => :json do
  59. World[rand1].to_json
  60. end
  61. get '/queries', :provides => :json do
  62. queries = (params[:queries] || 1).to_i
  63. queries = 1 if queries < 1
  64. queries = 500 if queries > 500
  65. # Benchmark requirements explicitly forbid a WHERE..IN here, so be good...
  66. worlds = randn(queries).map! { |id| World[id] }
  67. World.to_json :array => worlds
  68. end
  69. get '/fortunes' do
  70. @fortunes = Fortune.all
  71. @fortunes << Fortune.new(
  72. :id => 0,
  73. :message => 'Additional fortune added at request time.'.freeze
  74. )
  75. @fortunes.sort_by!(&:message)
  76. slim :fortunes
  77. end
  78. get '/updates', :provides => :json do
  79. queries = (params[:queries] || 1).to_i
  80. queries = 1 if queries < 1
  81. queries = 500 if queries > 500
  82. # Benchmark requirements explicitly forbid a WHERE..IN here, and specify
  83. # that each transaction only read and write a single record, so be good...
  84. worlds = randn(queries).map! do |id|
  85. World.db.transaction do
  86. World.for_update[id].tap do |world|
  87. world.update :randomNumber => rand1
  88. end
  89. end
  90. end
  91. World.to_json :array => worlds
  92. end
  93. end