KelpBench.pm 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package KelpBench;
  2. use v5.36;
  3. use Kelp::Base 'Kelp';
  4. ## Attributes
  5. attr database => sub {
  6. if (lc $ENV{DATABASE} eq 'mongodb') {
  7. require KelpBench::Mongo;
  8. return KelpBench::Mongo->new;
  9. }
  10. elsif (lc $ENV{DATABASE} eq 'mysql') {
  11. require KelpBench::DBI;
  12. return KelpBench::DBI->new;
  13. }
  14. else {
  15. die "unknown database chosen: $ENV{DATABASE}";
  16. }
  17. };
  18. ## Utilities
  19. sub validate_number ($self, $num, $min, $max)
  20. {
  21. return $min unless length($num // '') && $num !~ /\D/;
  22. return $min if $num < $min;
  23. return $max if $num > $max;
  24. return $num;
  25. }
  26. sub random_number ($self, $max = 10_000)
  27. {
  28. return int(rand($max) + 1);
  29. }
  30. sub random_id ($self)
  31. {
  32. # in case random ids were not the same as random numbers
  33. return $self->random_number(10_000);
  34. }
  35. sub get_random_entries ($self, $count)
  36. {
  37. $count = $self->validate_number($count, 1, 500);
  38. my @result;
  39. for (1 .. $count) {
  40. my $id = $self->random_id;
  41. my $row = $self->database->random_number($id);
  42. next unless $row;
  43. push @result, {
  44. id => $id,
  45. randomNumber => $row->{randomNumber}
  46. };
  47. }
  48. return \@result;
  49. }
  50. ## Framework code
  51. sub before_dispatch {} # skip trying to log access
  52. sub before_finalize {} # skip adding X-Framework
  53. sub build ($self)
  54. {
  55. $self->add_route([GET => '/plaintext'] => 'action_plaintext');
  56. $self->add_route([GET => '/json'] => 'action_json');
  57. $self->add_route([GET => '/db'] => 'action_db');
  58. $self->add_route([GET => '/queries'] => 'action_queries');
  59. $self->add_route([GET => '/fortunes'] => 'action_fortunes');
  60. $self->add_route([GET => '/updates'] => 'action_updates');
  61. }
  62. ## Registered route handlers
  63. ## Names prefixed with _action, because we did not separate a controller
  64. ## (Controllers would slow this down a bit due to reblessing of app object)
  65. sub action_plaintext ($self)
  66. {
  67. $self->res->text;
  68. return 'Hello, World!';
  69. }
  70. sub action_json ($self)
  71. {
  72. return { message => 'Hello, World!' };
  73. }
  74. sub action_db ($self)
  75. {
  76. my $id = $self->random_id;
  77. my $row = $self->database->random_number($id);
  78. return { id => $id, randomNumber => $row->{randomNumber} };
  79. }
  80. sub action_queries ($self)
  81. {
  82. return $self->get_random_entries($self->req->query_param('queries'));
  83. }
  84. sub action_fortunes ($self) {
  85. my $objects = $self->database->fortune;
  86. push $objects->@*, {
  87. id => 0,
  88. message => "Additional fortune added at request time."
  89. };
  90. $objects->@* = sort { $a->{message} cmp $b->{message} } $objects->@*;
  91. return $self->template('fortunes', { rows => $objects });
  92. }
  93. sub action_updates ($self)
  94. {
  95. my $arr = $self->get_random_entries($self->req->query_param('queries'));
  96. foreach my $row ($arr->@*) {
  97. $row->{randomNumber} = $self->random_number;
  98. $self->database->update($row->@{qw(id randomNumber)});
  99. }
  100. return $arr;
  101. };
  102. 1;