22
33# Our Rack application to be executed by rackup
44
5- require_relative 'pg_db'
5+ if RUBY_PLATFORM == 'java'
6+ require_relative 'db_jruby'
7+ else
8+ require_relative 'db'
9+ end
610require_relative 'config/auto_tune'
711require 'rack'
812require 'json'
13+ require 'time'
914require 'erb'
1015
11- if RUBY_PLATFORM == 'java'
12- DEFAULT_DATABASE_URL = 'jdbc:postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass'
13- else
14- DEFAULT_DATABASE_URL = 'postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass'
15- end
16+ DATABASE_URL = 'postgresql://tfb-database/hello_world?user=benchmarkdbuser&password=benchmarkdbpass'
17+ $db = connect ( DATABASE_URL )
1618
1719class HelloWorld
1820 QUERY_RANGE = ( 1 ..10_000 ) . freeze # range of IDs in the Fortune DB
@@ -42,30 +44,6 @@ class HelloWorld
4244 </body>
4345 </html>'
4446
45- def initialize
46- if defined? ( Puma ) || defined? ( Itsi )
47- max_connections = ENV . fetch ( 'MAX_THREADS' )
48- elsif defined? ( Iodine )
49- max_connections = ENV . fetch ( 'THREADS' )
50- else
51- max_connections = 512
52- end
53- @db = PgDb . new ( DEFAULT_DATABASE_URL , max_connections )
54- end
55-
56- def fortunes
57- fortunes = @db . select_fortunes
58- fortunes << { id : 0 , message : 'Additional fortune added at request time.' }
59- fortunes . sort_by! { |item | item [ :message ] }
60- buffer = String . new
61- buffer << TEMPLATE_PREFIX
62-
63- fortunes . each do |item |
64- buffer << "<tr><td>#{ item [ :id ] } </td><td>#{ ERB ::Escape . html_escape ( item [ :message ] ) } </td></tr>"
65- end
66- buffer << TEMPLATE_POSTFIX
67- end
68-
6947 def call ( env )
7048 case env [ 'PATH_INFO' ]
7149 when '/json'
@@ -74,20 +52,19 @@ def call(env)
7452 { message : 'Hello, World!' } . to_json
7553 when '/db'
7654 # Test type 2: Single database query
77- respond JSON_TYPE , @db . select_random_world . to_json
55+ id = random_id
56+ respond JSON_TYPE , $db. with { _1 . select_world ( id ) } . to_json
7857 when '/queries'
7958 # Test type 3: Multiple database queries
80- params = Rack ::Utils . parse_query ( env [ 'QUERY_STRING' ] )
81- queries = params [ 'queries' ]
82- respond JSON_TYPE , @db . select_worlds ( queries ) . to_json
59+ queries = bounded_queries ( env )
60+ respond JSON_TYPE , select_worlds ( queries ) . to_json
8361 when '/fortunes'
8462 # Test type 4: Fortunes
8563 respond HTML_TYPE , fortunes
8664 when '/updates'
8765 # Test type 5: Database updates
88- params = Rack ::Utils . parse_query ( env [ 'QUERY_STRING' ] )
89- queries = params [ 'queries' ]
90- respond JSON_TYPE , @db . update_worlds ( queries ) . to_json
66+ queries = bounded_queries ( env )
67+ respond JSON_TYPE , update_worlds ( queries ) . to_json
9168 when '/plaintext'
9269 # Test type 6: Plaintext
9370 respond PLAINTEXT_TYPE , 'Hello, World!'
@@ -120,4 +97,51 @@ def headers(content_type)
12097 }
12198 end
12299 end
100+
101+ def fortunes
102+ fortunes = $db. with ( &:select_fortunes ) . map ( &:to_h )
103+ fortunes << { 'id' => 0 , 'message' => 'Additional fortune added at request time.' }
104+ fortunes . sort_by! { |item | item [ 'message' ] }
105+ buffer = String . new
106+ buffer << TEMPLATE_PREFIX
107+
108+ fortunes . each do |item |
109+ buffer << "<tr><td>#{ item [ 'id' ] } </td><td>#{ ERB ::Escape . html_escape ( item [ 'message' ] ) } </td></tr>"
110+ end
111+ buffer << TEMPLATE_POSTFIX
112+ end
113+
114+ def update_worlds ( count )
115+ results = select_worlds ( count )
116+ ids = [ ]
117+ sql = String . new ( "UPDATE world SET randomnumber = CASE id " )
118+ results . each do |r |
119+ r [ 'randomnumber' ] = random_id
120+ ids << r [ 'id' ]
121+ sql << "when #{ r [ 'id' ] } then #{ r [ 'randomnumber' ] } "
122+ end
123+ sql << "ELSE randomnumber END WHERE id IN ( #{ ids . join ( ',' ) } )"
124+ $db. with { _1 . exec ( sql ) }
125+ results
126+ end
127+
128+ def select_worlds ( count )
129+ ids = ALL_IDS . sample ( count )
130+ $db. with do |conn |
131+ ids . map do |id |
132+ conn . select_world ( id )
133+ end
134+ end
135+ end
136+
137+ def random_id
138+ Random . rand ( QUERY_RANGE )
139+ end
140+
141+ def bounded_queries ( env )
142+ params = Rack ::Utils . parse_query ( env [ 'QUERY_STRING' ] )
143+
144+ queries = params [ 'queries' ] . to_i
145+ queries . clamp ( MIN_QUERIES , MAX_QUERIES )
146+ end
123147end
0 commit comments