boot.rb 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # frozen_string_literal: true
  2. require 'bundler/setup'
  3. require 'time'
  4. MAX_PK = 10_000
  5. ID_RANGE = (1..10_000).freeze
  6. ALL_IDS = ID_RANGE.to_a
  7. QUERIES_MIN = 1
  8. QUERIES_MAX = 500
  9. SEQUEL_NO_ASSOCIATIONS = true
  10. CONTENT_TYPE = 'Content-Type'
  11. JSON_TYPE = 'application/json'
  12. HTML_TYPE = 'text/html; charset=utf-8'
  13. PLAINTEXT_TYPE = 'text/plain'
  14. DATE_HEADER = 'Date'
  15. SERVER_HEADER = 'Server'
  16. SERVER_STRING =
  17. if defined?(PhusionPassenger)
  18. [
  19. PhusionPassenger::SharedConstants::SERVER_TOKEN_NAME,
  20. PhusionPassenger::VERSION_STRING
  21. ].join('/').freeze
  22. elsif defined?(Puma)
  23. Puma::Const::PUMA_SERVER_STRING
  24. elsif defined?(Unicorn)
  25. Unicorn::HttpParser::DEFAULTS['SERVER_SOFTWARE']
  26. end
  27. Bundler.require(:default) # Load core modules
  28. def connect(dbtype)
  29. Bundler.require(dbtype) # Load database-specific modules
  30. adapters = {
  31. mysql: { jruby: 'jdbc:mysql', mri: 'mysql2' },
  32. postgresql: { jruby: 'jdbc:postgresql', mri: 'postgres' }
  33. }
  34. opts = {}
  35. # Determine threading/thread pool size and timeout
  36. if defined?(JRUBY_VERSION)
  37. opts[:max_connections] = (2 * Math.log(Integer(ENV.fetch('MAX_CONCURRENCY')))).floor
  38. opts[:pool_timeout] = 10
  39. elsif defined?(Puma) && (threads = Puma.cli_config.options.fetch(:max_threads)) > 1
  40. opts[:max_connections] = (2 * Math.log(threads)).floor
  41. opts[:pool_timeout] = 10
  42. else
  43. Sequel.single_threaded = true
  44. end
  45. Sequel.connect \
  46. '%{adapter}://%{host}/%{database}?user=%{user}&password=%{password}' % {
  47. adapter: adapters.fetch(dbtype).fetch(defined?(JRUBY_VERSION) ? :jruby : :mri),
  48. host: 'tfb-database',
  49. database: 'hello_world',
  50. user: 'benchmarkdbuser',
  51. password: 'benchmarkdbpass'
  52. }, opts
  53. end
  54. DB = connect ENV.fetch('DBTYPE').to_sym
  55. # Define ORM models
  56. class World < Sequel::Model(:World)
  57. BY_ID = naked.where(id: :$id).prepare(:first, :world_by_id)
  58. UPDATE = where(id: :$id).prepare(:update, :world_update, randomnumber: :$randomnumber)
  59. def_column_alias(:randomnumber, :randomNumber) if DB.database_type == :mysql
  60. def self.batch_update(worlds)
  61. if DB.database_type == :mysql
  62. worlds.each do |world|
  63. UPDATE.(id: world[:id], randomnumber: world[:randomnumber])
  64. end
  65. else
  66. ids = []
  67. sql = String.new("UPDATE world SET randomnumber = CASE id ")
  68. worlds.each do |world|
  69. sql << "when #{world[:id]} then #{world[:randomnumber]} "
  70. ids << world[:id]
  71. end
  72. sql << "ELSE randomnumber END WHERE id IN ( #{ids.join(',')})"
  73. DB.run(sql)
  74. end
  75. end
  76. end
  77. class Fortune < Sequel::Model(:Fortune)
  78. # Allow setting id to zero (0) per benchmark requirements
  79. unrestrict_primary_key
  80. end
  81. [World, Fortune].each(&:freeze)
  82. DB.freeze