app.pl 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. use Mojolicious::Lite;
  2. use Mojo::Pg;
  3. use Mojo::Promise;
  4. use Cpanel::JSON::XS 'encode_json';
  5. use Scalar::Util 'looks_like_number';
  6. use Data::Dumper;
  7. # configuration
  8. {
  9. my $nproc = `nproc`;
  10. app->config(hypnotoad => {
  11. accepts => 0,
  12. clients => int( 256 / $nproc ) + 1,
  13. graceful_timeout => 1,
  14. requests => 10000,
  15. workers => $nproc,
  16. backlog => 256
  17. });
  18. }
  19. {
  20. my $db_host = 'tfb-database';
  21. helper pg => sub { state $pg = Mojo::Pg->new('postgresql://benchmarkdbuser:benchmarkdbpass@' . $db_host . '/hello_world')->max_connections(50) };
  22. }
  23. helper render_json => sub {
  24. my $c = shift;
  25. $c->res->headers->content_type('application/json');
  26. $c->render( data => encode_json(shift) );
  27. };
  28. # Routes
  29. get '/json' => sub { shift->helpers->render_json({message => 'Hello, World!'}) };
  30. get '/db' => sub { shift->helpers->render_query(1, {single => 1}) };
  31. get '/queries' => sub {
  32. my $c = shift;
  33. $c->helpers->render_query(scalar $c->param('queries'));
  34. };
  35. get '/fortunes' => sub {
  36. my $c = shift;
  37. $c->render_later;
  38. my $docs = $c->helpers->pg->db->query_p('SELECT id, message FROM Fortune')
  39. ->then(sub{
  40. my $docs = $_[0]->arrays;
  41. push @$docs, [0, 'Additional fortune added at request time.'];
  42. $c->render(fortunes => docs => $docs->sort(sub{ $a->[1] cmp $b->[1] }) )
  43. });
  44. };
  45. get '/updates' => sub {
  46. my $c = shift;
  47. $c->helpers->render_query(scalar $c->param('queries'), {update => 1});
  48. };
  49. get '/plaintext' => { text => 'Hello, World!', format => 'txt' };
  50. # Additional helpers (shared code)
  51. helper 'render_query' => sub {
  52. my ($self, $q, $args) = @_;
  53. $self->render_later;
  54. $args ||= {};
  55. my $update = $args->{update};
  56. $q = 1 unless looks_like_number($q);
  57. $q = 1 if $q < 1;
  58. $q = 500 if $q > 500;
  59. my $r = [];
  60. my $tx = $self->tx;
  61. my @queries;
  62. foreach (1 .. $q) {
  63. my $id = 1 + int rand 10_000;
  64. push @queries, $self->helpers->pg->db->query_p('SELECT id,randomnumber FROM World WHERE id=?', $id)
  65. ->then(sub{
  66. my $randomNumber = $_[0]->array->[0];
  67. return Mojo::Promise->new->resolve($id, $randomNumber)
  68. ->then(sub{
  69. if($update) {
  70. $randomNumber = 1 + int rand 10_000;
  71. return Mojo::Promise->all(
  72. Mojo::Promise->new->resolve($_[0], $randomNumber),
  73. $self->helpers->pg->db->query_p('UPDATE World SET randomnumber=? WHERE id=?', $randomNumber, $id)
  74. )
  75. ->then(sub {
  76. return $_[0];
  77. })
  78. }
  79. return [shift, shift];
  80. })
  81. });
  82. }
  83. Mojo::Promise->all(@queries)
  84. ->then(sub{
  85. my @responses = @_;
  86. foreach my $resp (@responses) {
  87. push @$r, { id => $resp->[0][0], randomNumber => $resp->[0][1] };
  88. }
  89. $r = $r->[0] if $args->{single};
  90. $self->helpers->render_json($r);
  91. })
  92. };
  93. app->start;
  94. __DATA__
  95. @@ fortunes.html.ep
  96. <!DOCTYPE html>
  97. <html>
  98. <head><title>Fortunes</title></head>
  99. <body>
  100. <table>
  101. <tr><th>id</th><th>message</th></tr>
  102. % foreach my $doc (@$docs) {
  103. <tr>
  104. <td><%= $doc->[0] %></td>
  105. <td><%= $doc->[1] %></td>
  106. </tr>
  107. % }
  108. </table>
  109. </body>
  110. </html>