Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Eight Point Oh

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Eight Point Oh

Avatar for Sebastian Riedel

Sebastian Riedel

September 08, 2018
Tweet

More Decks by Sebastian Riedel

Other Decks in Programming

Transcript

  1. 8.0

  2. openQA • 100+ Contributors • 320 Minion Workers • 2.7M

    Tests executed • 25 Years of Test Runtime • 700 Test Modules • 800 Bugs found
  3. Cavil • 110K Packages per Year • 27K License Patterns

    • 2TB of License Data • 122M Minion Jobs
  4. get '/slow' => sub { my $c = shift; sleep

    3; $c->render(text => 'Hello Mojo!'); };
  5. Mojo::IOLoop->subprocess( sub { my $subprocess = shift; sleep 3; return

    'Hello Mojo!'; }, sub { my ($subprocess, $error, @results) = @_; ... } );
  6. get '/slow' => sub { my $c = shift; Mojo::IOLoop->subprocess(

    sub { sleep 3; return 'Hello Mojo!'; }, sub { my ($subprocess, $error, $message) = @_; return $c->reply->exception($error) if $error; $c->render(text => $message); } ); };
  7. use Cwd qw(getcwd realpath); use File::Copy qw(copy move); use File::Find

    'find'; use File::Spec::Functions qw(abs2rel canonpath catfile file_name_is_absolute rel2abs splitdir); use File::Temp qw(tempdir tempfile);
  8. my $path = path('/home/sri/.vimrc'); # ["home", "sri", ".vimrc"] $path->to_array; #

    "/home/sri" $path->dirname; # ".vimrc" $path->basename;
  9. my $path = path('/home/sri'); for my $file ($path->list_tree->each) { say

    $file; } for my $file ($path->list->each) { say $file; }
  10. $path->basename; $path->child(...); $path->copy_to(...); $path->dirname; $path->is_abs; $path->list; $path->list_tree; $path->make_path; $path->move_to(...); $path->open(...);

    $path->realpath; $path->remove_tree; $path->sibling(...); $path->slurp; $path->spurt(...); $path->to_abs; $path->to_array; $path->to_rel(...); $path->to_string;
  11. package MyApp; use Mojo::Base 'Mojolicious'; sub startup { my $self

    = shift; my $config = $self->plugin('Config'); my $name = $config->{name}; my $r = $self->routes; $r->get('/' => {inline => '%= $name'}); } 1;
  12. 7.0

  13. use Test::More; use Test::Mojo; my $t = Test::Mojo->new(MyApp => {name

    => 'foo'}); $t->get_ok('/')->content_is('foo'); $t = Test::Mojo->new(MyApp => {name => 'bar'}); $t->get_ok('/')->content_is('bar'); done_testing; 8.0
  14. my $t = Test::Mojo->new('MyApp'); my $location_is = sub { my

    ($t, $value, $desc) = @_; $desc ||= "Location: $value"; local $Test::Builder::Level = $Test::Builder::Level + 1; return $t->success(is($t->tx->res->headers->location, $value, $desc)); }; $t->get_ok('/') ->status_is(302) ->$location_is('https://mojolicious.org'); 7.0
  15. package Test::Mojo::Role::Location; use Mojo::Base -role; use Test::More; sub location_is {

    my ($t, $value, $desc) = @_; $desc ||= "Location: $value"; local $Test::Builder::Level = $Test::Builder::Level + 1; return $t->success( is($t->tx->res->headers->location, $value, $desc)); } 1; 8.0
  16. my $followup_promise = $promise->then(sub { my $result = shift; ...

    return 1 + 1; }, sub { my $error = shift; ... return 2 + 2; });
  17. my $followup_promise = $promise->then(sub { my $result = shift; ...

    return $ua->get_p('https://mojolicious.org'); }, sub { my $error = shift; ... });
  18. $ua->get('https://mojolicious.org' => sub { my ($ua, $tx) = @_; say

    $tx->res->code; $ua->get('https://mojolicious.org' => sub { my ($ua, $tx) = @_; say $tx->res->code; $ua->get('https://mojolicious.org' => sub { my ($ua, $tx) = @_; say $tx->res->code; }); }); }); 7.0
  19. $ua->get_p('https://mojolicious.org')->then(sub { my $tx = shift; say $tx->res->code; return $ua->get_p('https://mojolicious.org');

    })->then(sub { my $tx = shift; say $tx->res->code; return $ua->get_p('https://mojolicious.org'); })->then(sub { my $tx = shift; say $tx->res->code; }); 8.0
  20. $ua->get_p('https://mojolicious.org')->then(sub { my $tx = shift; say $tx->res->code; return $ua->get_p('https://mojolicious.org');

    })->then(sub { my $tx = shift; say $tx->res->code; return $ua->get_p('https://mojolicious.org'); })->then(sub { my $tx = shift; say $tx->res->code; })->catch(sub { my $error = shift; ... });
  21. my $followup = Mojo::Promises->all(@promises); my $followup = Mojo::Promises->race(@promises); $promise =

    $promise->resolve(...); $promise = $promise->reject(...); my $followup = $promise->then(sub {...}, sub {...}); my $followup = $promise->catch(sub {...}); my $followup = $promise->finally(sub {...}); $promise->wait;
  22. HTTP/1.1 200 OK Date: Sat, 13 Sep 2014 16:48:29 GMT

    Content-Length: 11 Server: Mojolicious (Perl) Server-Timing: cpu;desc=CPU;dur=0.03, db;desc=PostgreSQL;dur=0.6 Hello Mojo!
  23. $c->timing->begin('stuff'); sleep 3; my $elapsed = $c->timing->elapsed('stuff'); my $rps =

    $c->timing->rps($elapsed); $c->app->log->debug("Stuff took $elapsed seconds ($rps/s)");
  24. $app->hook(before_server_start => sub { my ($server, $app) = @_; return

    unless $server->isa('Mojo::Server::Daemon'); say "Manager $$ started"; $server->on( spawn => sub { my ($server, $pid) = @_; say "Worker $pid started"; } ) if $server->isa('Mojo::Server::Prefork'); });
  25. $app->hook(before_dispatch => sub { my $c = shift; my $id

    = $c->req->headers->header('X-Request-Id'); $c->req->request_id($id); });
  26. ???

  27. use DBD::Pg ':async'; use Mojo::IOLoop; my $dbh = DBI->connect( 'dbi:Pg:dbname=postgres;host=127.0.0.1;port=5432',

    'postgres', '', { AutoCommit => 1, AutoInactiveDestroy => 1, PrintError => 0, PrintWarn => 0, RaiseError => 1 } ); my $sth = $dbh->prepare('select 1', {pg_async => PG_ASYNC}); $sth->execute; open my $handle, '<&', $dbh->{pg_socket} or die "Can't dup: $!"; Mojo::IOLoop->singleton->reactor->io( $handle => sub { return unless $dbh->pg_ready; my $result = $sth->pg_result; my $data = $sth->fetchall_arrayref; ... Mojo::IOLoop->stop; } ); Mojo::IOLoop->start;
  28. my $arrays = $results->arrays; my $hashes = $results->hashes; my $array

    = $results->array; my $hash = $results->hash; my $text = $results->text; my $names = $results->columns; my $num = $results->rows;
  29. my $users = $pg->db->query('select * from users')->hashes; for my $user

    ($users->each) { say $user->{first_name}; say $user->{last_name}; }
  30. $db->insert('users', {name => 'Joel'}); my $id = $db->select('users', '*', {name

    => 'Joel'})->hash->{id}; $db->update('users', {name => 'jberger'}, {id => $id}); $db->delete('users', {name => 'jberger'});
  31. $db->select_p('users', '*', {name => ‘Marcus’})->then( sub { my $results =

    shift; say $results->hash->{id}; }, sub { my $error = shift; warn $error; } );
  32. # "select * from users limit 10 offset 20" $db->select('users',

    '*', undef, {limit => 10, offset => 20});
  33. # "insert into t (a) values ('b') on conflict (a)

    do update set a = 'c'" $db->insert('t', {a => 'b'}, {on_conflict => [a => {a => 'c'}]}); # "select * from foo join bar on (bar.foo_id = foo.id)" $db->select(['foo', ['bar', foo_id => 'id']]); # "select * from some_table where id = 1 for update" $db->select('some_table', '*', {id => 1}, {for => 'update'});
  34. $pg->pubsub->listen(foo => sub { my ($pubsub, $payload) = @_; say

    "foo: $payload"; }); $pg->pubsub->notify(foo => 'PostgreSQL rocks!');
  35. -- 1 up create table if not exists posts (

    id serial primary key, title text, body text ); -- 1 down drop table if exists posts;
  36. -- 1 up create table if not exists posts (

    id serial primary key, title text, body text ); -- 2 up alter tabl posts add column slug text; -- 1 down drop table if exists posts;
  37. package Minion::Backend::MyBackend; use Mojo::Base 'Minion::Backend'; sub broadcast {...} sub dequeue

    {...} sub enqueue {...} sub fail_job {...} sub finish_job {...} sub history {...} sub list_jobs {...} sub list_locks {...} sub list_workers {...} sub lock {...} sub note {...} sub receive {...} sub register_worker {...} sub remove_job {...} sub repair {...} sub reset {...} sub retry_job {...} sub stats {...} sub unlock {...} sub unregister_worker {...}
  38. $minion->add_task(foo => sub { my ($job, @args) = @_; sleep

    5; say $job->finish({hello => 'mojo'}); });
  39. my $id_one = $minion->enqueue('resize', [...]); my $id_two = $minion->enqueue('resize', [...]);

    my $pack_id = $minion->enqueue( 'pack', [...], {parents => [$id_one ,$id_two]});
  40. $minion->add_task(foo => sub { my ($job, @args) = @_; warn

    'Some important information!'; die 'Hello Mojo!'; });