123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- # frozen_string_literal: true
- require 'time'
- # Our Rack application to be executed by rackup
- class HelloWorld
- MAX_PK = 10_000
- ID_RANGE = (1..10_000).freeze
- ALL_IDS = ID_RANGE.to_a
- QUERIES_MIN = 1
- QUERIES_MAX = 500
- CONTENT_TYPE = 'Content-Type'
- CONTENT_LENGTH = 'Content-Length'
- JSON_TYPE = 'application/json'
- HTML_TYPE = 'text/html; charset=utf-8'
- PLAINTEXT_TYPE = 'text/plain'
- DATE = 'Date'
- SERVER = 'Server'
- SERVER_STRING = "Rack"
- def bounded_queries(env)
- params = Rack::Utils.parse_query(env['QUERY_STRING'])
- queries = params['queries'].to_i
- queries.clamp(QUERIES_MIN, QUERIES_MAX)
- end
- # Return a random number between 1 and MAX_PK
- def rand1
- rand(MAX_PK).succ
- end
- def db
- World::BY_ID.(id: rand1)
- end
- def queries(env)
- ids = ALL_IDS.sample(bounded_queries(env))
- DB.synchronize do
- ids.map do |id|
- World::BY_ID.(id: id)
- end
- end
- end
- def fortunes
- fortunes = Fortune.all
- fortunes << Fortune.new(
- id: 0,
- message: 'Additional fortune added at request time.'
- )
- fortunes.sort_by!(&:message)
- html = String.new(<<~'HTML')
- <!DOCTYPE html>
- <html>
- <head>
- <title>Fortunes</title>
- </head>
- <body>
- <table>
- <tr>
- <th>id</th>
- <th>message</th>
- </tr>
- HTML
- fortunes.each do |fortune|
- html << <<~"HTML"
- <tr>
- <td>#{fortune.id}</td>
- <td>#{Rack::Utils.escape_html(fortune.message)}</td>
- </tr>
- HTML
- end
- html << <<~'HTML'
- </table>
- </body>
- </html>
- HTML
- end
- def updates(env)
- ids = ALL_IDS.sample(bounded_queries(env))
- DB.synchronize do
- worlds =
- ids.map do |id|
- world = World::BY_ID.(id: id)
- world[:randomnumber] = rand1
- world
- end
- World.batch_update(worlds)
- worlds
- end
- end
- def call(env)
- case env['PATH_INFO']
- when '/json'
- # Test type 1: JSON serialization
- respond JSON_TYPE, { message: 'Hello, World!' }.to_json
- when '/db'
- # Test type 2: Single database query
- respond JSON_TYPE, db.to_json
- when '/queries'
- # Test type 3: Multiple database queries
- respond JSON_TYPE, queries(env).to_json
- when '/fortunes'
- # Test type 4: Fortunes
- respond HTML_TYPE, fortunes
- when '/updates'
- # Test type 5: Database updates
- respond JSON_TYPE, updates(env).to_json
- when '/plaintext'
- # Test type 6: Plaintext
- respond PLAINTEXT_TYPE, 'Hello, World!'
- end
- end
- private
- def respond(content_type, body)
- [
- 200,
- headers(content_type, body),
- [body]
- ]
- end
- if defined?(Unicorn)
- def headers(content_type, body)
- {
- CONTENT_TYPE => content_type,
- SERVER => SERVER_STRING,
- CONTENT_LENGTH => body.bytesize.to_s
- }
- end
- elsif defined?(Puma)
- def headers(content_type, _)
- {
- CONTENT_TYPE => content_type,
- SERVER => SERVER_STRING,
- DATE => Time.now.utc.httpdate
- }
- end
- else
- def headers(content_type, _)
- {
- CONTENT_TYPE => content_type,
- SERVER => SERVER_STRING
- }
- end
- end
- end
|