hello_world.rb 3.3 KB

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