hello_world.rb 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # frozen_string_literal: true
  2. # Our Rack application to be executed by rackup
  3. require_relative 'pg_db'
  4. require_relative 'config/auto_tune'
  5. require 'rack'
  6. if RUBY_PLATFORM == 'java'
  7. require 'json'
  8. DEFAULT_DATABASE_URL = 'jdbc:postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass'
  9. else
  10. require 'oj'
  11. Oj.mimic_JSON
  12. DEFAULT_DATABASE_URL = 'postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass'
  13. end
  14. class HelloWorld
  15. QUERY_RANGE = (1..10_000).freeze # range of IDs in the Fortune DB
  16. ALL_IDS = QUERY_RANGE.to_a # enumeration of all the IDs in fortune DB
  17. MIN_QUERIES = 1 # min number of records that can be retrieved
  18. MAX_QUERIES = 500 # max number of records that can be retrieved
  19. CONTENT_TYPE = 'Content-Type'
  20. CONTENT_LENGTH = 'Content-Length'
  21. JSON_TYPE = 'application/json'
  22. HTML_TYPE = 'text/html; charset=utf-8'
  23. PLAINTEXT_TYPE = 'text/plain'
  24. DATE = 'Date'
  25. SERVER = 'Server'
  26. SERVER_STRING = if defined?(PhusionPassenger)
  27. 'Passenger'
  28. elsif defined?(Puma)
  29. Puma::Const::PUMA_SERVER_STRING
  30. elsif defined?(Unicorn)
  31. 'Unicorn'
  32. elsif defined?(Falcon)
  33. 'Falcon'
  34. else
  35. ' Ruby Rack'
  36. end
  37. TEMPLATE_PREFIX = '<!DOCTYPE html>
  38. <html>
  39. <head>
  40. <title>Fortunes</title>
  41. </head>
  42. <body>
  43. <table>
  44. <tr>
  45. <th>id</th>
  46. <th>message</th>
  47. </tr>'
  48. TEMPLATE_POSTFIX = '</table>
  49. </body>
  50. </html>'
  51. def initialize
  52. if defined?(Puma)
  53. num_workers, num_threads = auto_tune
  54. num_threads = [num_threads, 32].min
  55. max_connections = num_workers * num_threads
  56. else
  57. max_connections = 512
  58. end
  59. @db = PgDb.new(DEFAULT_DATABASE_URL, max_connections)
  60. end
  61. def respond(content_type, body = '')
  62. [
  63. 200,
  64. {
  65. CONTENT_TYPE => content_type,
  66. DATE => Time.now.utc.httpdate,
  67. SERVER => SERVER_STRING,
  68. CONTENT_LENGTH => body.bytesize.to_s
  69. },
  70. [body]
  71. ]
  72. end
  73. def fortunes
  74. fortunes = @db.select_fortunes
  75. fortunes << { id: 0, message: 'Additional fortune added at request time.' }
  76. fortunes.sort_by! { |item| item[:message] }
  77. buffer = String.new
  78. buffer << TEMPLATE_PREFIX
  79. fortunes.each do |item|
  80. buffer << "<tr><td>#{item[:id]}</td><td>#{Rack::Utils.escape_html(item[:message])}</td></tr>"
  81. end
  82. buffer << TEMPLATE_POSTFIX
  83. end
  84. def call(env)
  85. case env['PATH_INFO']
  86. when '/json'
  87. # Test type 1: JSON serialization
  88. respond JSON_TYPE,
  89. { message: 'Hello, World!' }.to_json
  90. when '/db'
  91. # Test type 2: Single database query
  92. respond JSON_TYPE, @db.select_random_world.to_json
  93. when '/queries'
  94. # Test type 3: Multiple database queries
  95. params = Rack::Utils.parse_query(env['QUERY_STRING'])
  96. queries = params['queries']
  97. respond JSON_TYPE, @db.select_worlds(queries).to_json
  98. when '/fortunes'
  99. # Test type 4: Fortunes
  100. respond HTML_TYPE, fortunes
  101. when '/updates'
  102. # Test type 5: Database updates
  103. params = Rack::Utils.parse_query(env['QUERY_STRING'])
  104. queries = params['queries']
  105. respond JSON_TYPE, @db.update_worlds(queries).to_json
  106. when '/plaintext'
  107. # Test type 6: Plaintext
  108. respond PLAINTEXT_TYPE, 'Hello, World!'
  109. end
  110. end
  111. end