Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Mojolicious / Hypnotoad / concurrency / data scope (SOLVED)

by 1nickt (Canon)
on Jan 08, 2018 at 18:03 UTC ( [id://1206927]=note: print w/replies, xml ) Need Help??


in reply to Mojolicious / Hypnotoad / concurrency / data scope

Answering myself here. I couldn't get an answer from the doc, so I simply wrote a comprehensive test.

With a Mojolicious app running under hypnotoad with 12 workers, set to accept up to 100 concurrent client connections per worker, with Log::Any code setting an ID value in the log context in the library used by the route controller, each request did indeed receive a unique ID. Tested with 10,000 requests from 50 parallel HTTP clients.

🤙

Update: As suggested by Your_Mother, here is the code I used for testing. I wanted to see whether (a) I would get a unique ID per request when using the Log::Any context, and (b) this was true when using a second library, getting a logger there and logging messages.

To run the test for yourself, save all these files into a single directory, change into it, and do:

$ hypnotoad myapp.pl $ prove tracking.t

# tracking.t use strict; use warnings; use Test::More; use Parallel::ForkManager; use HTTP::Tiny; use List::Util qw( all ); use Path::Tiny; my $log_file = '/tmp/test.log'; path( $log_file )->append( { truncate => 1 }, '' ); my $url = 'http://localhost:8080/hello'; my $pm = new Parallel::ForkManager(50); my $ua = HTTP::Tiny->new; for ( 1 .. 10_000 ) { $pm->start and next; my $res = $ua->get( $url ); $pm->finish; } $pm->wait_all_children; my %ids; my $count = 0; for ( path( $log_file )->lines({ chomp => 1 }) ) { $count++; (my $id) = /"([^"]*)/; $ids{ $id }++; } is( $count, 20_000, '20,000 lines in the log file' ) +; is( scalar keys %ids, 10_000, '10,000 IDs' ); ok( (all { $_ == 2 } values( %ids )), 'each key was seen twice' ); done_testing; __END__
# myapp.pl use strict; use warnings; $|++; use Log::Any::Adapter 'File', '/tmp/test.log'; use Mojolicious::Commands; use MyApp; Mojolicious::Commands->start_app('MyApp'); __END__
# MyApp.pm package MyApp { use Mojo::Base 'Mojolicious'; sub startup { my $self = shift; $self->config( hypnotoad => { workers => 12, clients => 100, accepts => 100, }, ); $self->routes->get('/hello')->to('foo#hello'); } }; package MyApp::Controller::Foo { use Mojo::Base 'Mojolicious::Controller'; use Digest::MD5 qw( md5_hex ); use Time::HiRes qw( time ); use MyLib; sub hello { my $self = shift; my $obj = MyLib->new; $obj->log->context->{id} = md5_hex(time . $$); $obj->log->debug('Hello from the route'); my $txt = $obj->other_class_action(42); $self->render(text => $txt); } }; 1;
# MyLib.pm use strict; use warnings; package MyLib { use Log::Any; use OtherLib; use Moo; has log => ( is => 'ro', default => sub { Log::Any->get_logger }, ); sub other_class_action { my ( $self, $val ) = @_; OtherLib::do_action( $val ); } }; 1;
# OtherLib.pm use strict; use warnings; package OtherLib { use Log::Any '$log'; sub do_action { my $val = shift; my $data = { value => $val }; $log->debugf( 'Acting with %s', $data ); return sprintf 'The answer is %s', $val; } }; 1;

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: Mojolicious / Hypnotoad / concurrency / data scope (SOLVED)
by Your Mother (Archbishop) on Jan 08, 2018 at 18:28 UTC

    That's great. You might post a gist of the code? Or even the code here, if you're happy with it, so others would have the skeleton for testing.

      I've updated my node above with the code I used for testing (stripped of in-house stuff).

      Hope this helps!


      The way forward always starts with a minimal test.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1206927]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (2)
As of 2024-04-20 04:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found