app-async.psgi 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. use strict; use feature 'state';
  2. use JSON::XS 'encode_json';
  3. use AnyEvent; use EV;
  4. use AnyEvent::DBI;
  5. use Unix::Processors;
  6. use List::Util qw'min max';
  7. my @dsn = ('dbi:mysql:database=hello_world;host=tfb-database;port=3306', 'benchmarkdbuser', 'benchmarkdbpass');
  8. my $query = 'select randomNumber, id from World where id = ?';
  9. sub {
  10. my $env = shift;
  11. my $path = $env->{PATH_INFO};
  12. return [200, [qw(Content-Type application/json)], [encode_json(+{ message => 'Hello, World!' })]] if $path eq '/json';
  13. return [200, [qw(Content-Type text/plain)], ['Hello, World!']] if $path eq '/plaintext';
  14. if ($path eq '/db') {
  15. state $cpus = Unix::Processors->new->max_online;
  16. state $dbh = [map AnyEvent::DBI->new(@dsn, on_error => sub { warn }), 1 .. $cpus * 4];
  17. state $dbh_idx = 0;
  18. my ($n) = ($env->{QUERY_STRING} // '' ) =~ m/queries=(\d+)/;
  19. $n = max(1, min($n//1, 500));
  20. return sub {
  21. my $res = shift;
  22. my @rs; my $cv = AE::cv;
  23. my $done_cb = sub { $res->([200, [qw(Content-Type application/json)], [encode_json($env->{QUERY_STRING} ? \@rs : $rs[0] // {})]]) };
  24. for my $qn (1..$n) {
  25. $cv->begin($done_cb);
  26. my $id = int(rand 10000) + 1;
  27. $dbh->[$dbh_idx++]->exec($query, $id, sub {
  28. my (undef, $rows) = @_;
  29. push @rs, map +{ id => $id, randomNumber => 0+ $_->[0] }, @$rows;
  30. $cv->end;
  31. });
  32. $dbh_idx = $dbh_idx % @$dbh if $dbh_idx >= @$dbh;
  33. }
  34. }
  35. }
  36. [404, [qw(Content-Type application/json)], ['not found']]
  37. }