SlideShare a Scribd company logo
1 of 114
print STDERR “timeoutn”;

timeout


warn(“timeout”);

timeout at test.pl line 8.
sub logf {
    my ($level,$message) = @_;
    my ($pkg,$file,$line) = caller;
    my @time = localtime;
    warn sprintf "%04d-%02d-%02dT%02d:%02d:%02d 
      [%s] %s at %s line %d.n",
        $time[5]+1900, $time[4]+1, @time[3,2,1,0],
        $level, $message,
        $file, $line;
}

logf(“WARN”,”timeout”);
logf(“INFO”,”foo bar”);


2011-10-05T09:41:30 [WARN] timeout at test.pl line 10.
2011-10-05T09:41:30 [INFO] foo bar at test.pl line 11.
➔
2011-10-05T09:41:30
[WARN]
[/entry/foobar]
failed request: http://ad.net/ read timeout
at /path/to/Controler/Entry.pm line 10.
use Log::Minimal;

# stack trace
debugf(‘blah blah blah’);
infof(“server start $$”);
critf("%s","foo");
warnf("%d %s", 1, "foo");

# stack trace
debugff(‘blah blah blah’);
infoff(“server start $$”);
critff("%s","foo");
warnff("%d %s", 1, "foo");
use Log::Minimal;

debugf(‘blah blah blah’); #

local $ENV{LM_DEBUG} = 1;
debugf(‘blah blah blah’); #


2011-10-05T09:41:30 [DEBUG] blah.. at test.pl line 11.
#
local $Log::Minimal::PRINT = sub {
    my ( $time, $type, $message, $trace) = @_;
    warn(“$time [$type] $message $tracen”);
};

#
open( my $fh, ">>", "app.log");
local $Log::Minimal::PRINT = sub {
    my ( $time, $type, $msg, $tr, $r_msg ) = @_;
    print $fh “$time [$type] $r_msg $trn”;
};
#
local $Log::Minimal::AUTODUMP = 1;
warnf(“response => %s”,$res);


2011-05-11T15:56:14 [WARN] response => [200,
['Content-Type','text/plain'],['OK']] at ..


#
local $Log::Minimal::COLOR = 1;
warnf(“hirose31”);


2011-05-11T15:56:14 [WARN] hirose31 at ..
use Log::Minimal;
use Plack::Builder;
builder {
    enable "Log::Minimal", autodump => 1;
    sub {
        my $env = shift;
        warnf("warn");
        debugf("debug");
        ...
    }
};



$ plackup -a demo.psgi
2011-05-11T16:32:24 [WARN] [/foo/bar/baz] warn at /tmp/
demo.psgi line 8
2011-05-11T16:32:24 [DEBUG] [/foo/bar/baz] debug at /tmp/
demo.psgi line 9
use Log::Minimal;
use Parallel::Prefork;

my $pm = Parallel::Prefork->new();
while ( $pm->signal_received ne 'TERM' ) {
    $pm->start(sub {
        local $Log::Minimal::AUTODUMP = 1;
        local $Log::Minimal::COLOR = 1;
        while (1) {
            my $job = $queue->dequeue;
            local $Log::Minimal::PRINT = sub {
                 my ( $time, $type, $message, $trace) = @_;
                warn(“$$ [“,$job->name,”] [$type] $message $trace”);
            };
            ...
        }
    });
}
SELECT   * FROM entries
 WHERE   created_at >= '2011-10-05 00:00:00'
   AND   created_at < '2011-10-06 00:00:00'
   AND   status != 0;




Data::Entry->search({
    -and => [
        created_at => {'>=','2011-10-05 00:00:00' },
        created_at => {'<','2011-10-06 00:00:00' },
    ],
    status => { '!=', 0 }
});
SELECT   * FROM entries
 WHERE   created_at >= '2011-10-05 00:00:00'
   AND   created_at < '2011-10-06 00:00:00'
   AND   status != 0;




Data::Entry->search({
    -and => [
        created_at => {'>=','2011-10-05 00:00:00' },
        created_at => {'<','2011-10-06 00:00:00' },
    ],
    status => { '!=', 0 }
});
SELECT   * FROM entries
 WHERE   created_at >= '2011-10-05 00:00:00'
   AND   created_at < '2011-10-06 00:00:00'
   AND   status != 0;




Data::Entry->search({
    -and => [
        created_at => {'>=','2011-10-05 00:00:00' },
        created_at => {'<','2011-10-06 00:00:00' },
    ],
    status => { '!=', 0 }
});
my $dbh = DBIx::Sunny->connect(
 ‘dsn’,‘user’,‘passwd’,
);


✓   RaiseError => 1
✓   PrintError= > 0
✓   ShowErrorStatement => 1
✓   AutoInactiveDestroy => 1
✓   sqlite_unicode/mysql_enable_utf8 => 1
✓   mysql_auto_reconnect => 0
my $sth = $dbh->prepare(“SELECT *
 FROM entries
 WHERE ..”);




SELECT /* test.pl line 941 */ *
  FROM entries
  WHERE ..
selectrow_arrayref($query, {}, @bind);




selectrow_hashref($query, {}, @bind);




selectall_arrayref($query, { Slice => {} }, @bind);




prepare($query) && execute(@bind)
my $builder = SQL::Maker->new(
    driver => 'mysql',
);
my $dbh = DBIx::Sunny->connect(...);

my ($sql, @binds) = $builder->select(
    'user',
    ['*'],
    {name => 'john'},
    {order_by => 'user_id DESC'}
);

my $rows = $dbh->select_row($sql,@binds);
my $dbh = DBI->connect($dsn,$user,$pass,{...});
while ( my $job = $queue->dequeue ) {
    ....
}


my $DBH;
sub get_dbh {
    $DBH ||= DBI->connect($dsn,$user,$pass,{...});
    $DBH;
}
while ( my $job = $queue->dequeue ) {
    my $dbh = get_dbh();
    ....
}


sub get_dbh {
    DBI->connect_cached($dsn,$user,$pass,{...});
}
while ( my $job = $queue->dequeue ) {
    my $dbh = get_dbh();
    ....
}
my $dbh = DBI->connect($dsn,$user,$pass,{...});
while ( my $job = $queue->dequeue ) {
    ....
}


my $DBH;
sub get_dbh {
    $DBH ||= DBI->connect($dsn,$user,$pass,{...});
    $DBH;
}
while ( my $job = $queue->dequeue ) {
    my $dbh = get_dbh();
    ....
}


sub get_dbh {
    DBI->connect_cached($dsn,$user,$pass,{...});
}
while ( my $job = $queue->dequeue ) {
    my $dbh = get_dbh();
    ....
}
> SHOW PROCESSLIST;
+--------+-------------+--------------------+---------+---------+-------+----------+------+
| Id     | User        | Host               | db      | Command | Time | State     | Info |
+--------+-------------+--------------------+---------+---------+-------+----------+------+
|      1 | system user |                    | NULL    | Connect | 4851 | Wait... | NULL |
|      2 | system user |                    | NULL    | Connect | 1     | Has r... | NULL |
| 235873 | www-slave   | 10.0.xxx.39:33018 | cluster | Sleep    | 8     |          | NULL |
| 278334 | www-slave   | 10.0.xxx.39:37627 | cluster | Sleep    | 1206 |           | NULL |
| 365403 | www-slave   | 10.0.xxx.39:43957 | cluster | Sleep    | 1259 |           | NULL |
| 378019 | www-slave   | 10.0.xxx.39:45098 | cluster | Sleep    | 138   |          | NULL |
| 397336 | www-slave   | 10.0.xxx.39:48595 | cluster | Sleep    | 377   |          | NULL |
| 404611 | www-slave   | 10.0.xxx.206:60525 | cluster | Sleep   | 44    |          | NULL |
| 405048 | www-slave   | 10.0.xxx.206:60645 | cluster | Sleep   | 119   |          | NULL |
| 405091 | www-slave   | 10.0.xxx.58:51982 | cluster | Sleep    | 1104 |           | NULL |
.....
811 rows in set (0.00 sec)
my $sc = start_scope_container(); #
scope_container(‘key1’,‘value1’);
$value = scope_container(‘key1’); #value

sub hoge {
    scope_container(‘key2’,‘foobar’);
}

{
    my $sc2 = start_scope_container(); #
    $value = scope_container(‘key1’); #value
    scope_container(‘key1’,‘blahblah’);
    hoge();
    $value = scope_container(‘key1’); #blahblah
    $value = scope_container(‘key2’); #foobar
    undef $sc2;
}

$value = scope_container(‘key1’); #value
$value = scope_container(‘key2’); #undefined
my %DATA; #
$DATA{'key1'} = 'value1';
$value = $DATA{'key1'} #value

sub hoge {
    $DATA{'key2'} = 'foobar';
}

{
    local %DATA; #
    $value = $DATA{'key1'} #value
    $DATA{'key1'} = ‘blahblah’
    hoge();
    $value = $DATA{'key1'}; #blahblah
    $value = $DATA{'key2'} #foobar
}

$value = $DATA{'key1'}; #value
$value = $DATA{'key2'}; #undefined
sub get_dbh {
    my $dsn = shift

    my $cache = scope_container($dsn);
    reutrn $cache if $cache;

    my $dbh = DBIx:Sunny->connect($dsn,$user,$pass);
    scope_container($dsn, $dbh);
    return $dbh;
}

while ( my $job = $queue->dequeue ) {
    my $sc = start_scope_container();
    my $dbh = get_dbh(); #new connection
    my $dbh2 = get_dbh(); #cached
    ..
    # disconnect
}
use Scope::Container;
use Scope::Container::DBI;

sub get_dbh {
    Scope::Container::DBI->connect($dsn,$user,$pass,{}):
}

for my $id (1..$max) {
    my $sc = start_scope_container();

    get_dbh()->do(...); #new connection
    get_dbh()->select_row(...); #cache

    undef $sc; #
}
# DBI
local $Scope::Container::DBI::DBI_CLASS = “Amon2::DBI”;
my $dbh = Scope::Container::DBI->connect(
    $dsn,$user,$pass,{});



#       slave    1
my $dbh = Scope::Container::DBI->connect(
    [$dsn1,$user,$pass,{}],
    [$dsn2,$user,$pass,{}],
    [$dsn3,$user,$pass,{}],
);
use Plack::Builder;

builder {
    enable “Scope::Container”;
    $app;
};



# Plack::Middleware::Scope::Container
sub call {
    my ( $self, $env) = @_;
    my $container = start_scope_container();
    $self->app->($env);
}
key1   key2   key3   key4   key5   key6    key7   key8   key9




        memcached1      memcached2        memcached3
key1   key2   key3   key4   key5   key6    key7   key8   key9




        memcached1      memcached2        memcached3
key1   key2   key3   key4   key5   key6    key7   key8   key9




        memcached1      memcached2        memcached3
key1   key2   key3   key4   key5   key6    key7   key8   key9




        memcached1      memcached2        memcached3
App   App




mem       DB
App   App      App   App




mem       DB   mem
App   App      App   App




mem       DB   mem       DB
use Cache::Memcached::IronPlate;
use Cache::Memcached::Fast;

my $memd = Cache::Memcached::IronPlate->new(
    cache => Cache::Memcached::Fast->new(...),
);

$memd->get
$memd->get_multi
$memd->set
$memd->add
$memd->replace
$memd->append
$memd->prepend
$memd->incr
$memd->counter
$memd->decr
$memd->delete
set(‘key:dup’,val,exp)     get(‘key:dup’)




      IronPlate               IronPlate


 set key:dist:{1..3}     get key:dist:{1..3}



mem1 mem2 mem3           mem1 mem2 mem3
set(‘key:dist’,val,exp)      get(‘key:dist’)




       IronPlate                IronPlate


 set key:dist:{1..30}     get key:dist:rand(30)



 mem1 mem2 mem3           mem1 mem2 mem3
use Cache::Isolator;
use Cache::Memcached::Fast;
 
my $isolator = Cache::Isolator->new(
    cache => Cache::Memcached::Fast->new(...),
);

$isolator->get(key);
$isolator->set(key,val,expires);
set(‘key’,val,30)                 set(‘key’,val,30)




         Isolator                          Isolator


set key 30      set key:earlyexp 20




     mem1      mem2                   mem1       mem2
use Cache::Isolator;
use Cache::Memcached::Fast;
 
my $isolator = Cache::Isolator->new(
    cache => Cache::Memcached::Fast->new(...),
    early_expires_ratio => 10,
    expires_before => 10
);

$isolator->get(key);
$isolator->set(key,val,expires);
use Cache::Isolator;
use Cache::Memcached::Fast;
 
my $isolator = Cache::Isolator->new(
    cache => Cache::Memcached::Fast->new(...),
    concurrency => 3,
);

$isolator->get_or_set(key, sub {
    my $dbh = get_dbh();
    $dbh->select_all(heavy_sql);
}, expires);
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
DB


response   memcached
use Plack::Builder;
use File::Temp;

builder {
  enable "ServerStatus::Lite",
    path => '/___server-status',
    allow => [‘127.0.0.1’,‘192.168.0.0/16’],
    scoreboard => File::Temp::tempdir(CLEANUP => 1);
  $app
};
$ curl http://localhost:5000/___server-status
Uptime: 1318372692
BusyWorkers: 3
IdleWorkers: 27
--
pid status remote_addr host method uri protocol
1522 A 127.0.0.1 localhost:5000 GET /___server-status HTTP/1.1
1523 _ 192.168.67.3 192.168.67.4:5000 GET /foo/bar HTTP/1.0
1526 _ 192.168.67.5 192.168.67.4:5000 GET /foo/bar HTTP/1.0
...
use Parallel::Prefork;
use Parallel::Scoreboard;

my $sb = Parallel::Scoreboard->new(
  base_dir => ‘/var/run/example_worker’ );

my $pm = Parallel::Prefork->new({...});
while ( $pm->signal_received !~ m!^(?:TERM|INT)$! ) {
  $pm->start(sub{
    $sb->update('.');
    while(1) {
      my $job = $queue->dequeue;
      $sb->update('A');
      #work work work
      $sb->update('.');
    }
  });
}
use Parallel::Prefork;
use Parallel::Scoreboard;

my $sb = Parallel::Scoreboard->new(
  base_dir => ‘/var/run/example_worker’ );

my $pm = Parallel::Prefork->new({...});
while ( $pm->signal_received !~ m!^(?:TERM|INT)$! ) {
  $pm->start(sub{      idle
    $sb->update('.');
    while(1) {
      my $job = $queue->dequeue;
      $sb->update('A');
      #work work work       busy
      $sb->update('.');
    }
  });                     idle
}
# scoreboard.psgi
my $sb = Parallel::Scoreboard->new(
  base_dir => ‘/var/run/example_worker’ );
sub {
  my $env = shift;
  my $stats = $scoreboard->read_all();
  my $busy = 0;
  my $idle = 0;
  for my $pid ( sort { $a <=> $b } keys %$stats) {
    if ( $stats->{$pid} =~ m!^A! ) {
      $busy++;
    } else {                       busy
      $idle++;
    }
  }
  return [200,['Content-Type'=>'plain/text'],
           ["BusyWorkers: $busynIdleWorkers: $idle"]];
};
#
$ plackup -p 5001 -a scoreboard.psgi

#
$ curl http://localhost:5001/___server-status
BusyWorkers: 6
IdleWorkers: 4
192.188.67.2
               idle




                  busy
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011

More Related Content

What's hot

Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionIan Barber
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
Drush. Secrets come out.
Drush. Secrets come out.Drush. Secrets come out.
Drush. Secrets come out.Alex S
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Kris Wallsmith
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHPTaras Kalapun
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 

What's hot (20)

Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 Version
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
Drush. Secrets come out.
Drush. Secrets come out.Drush. Secrets come out.
Drush. Secrets come out.
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Daily notes
Daily notesDaily notes
Daily notes
 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database api
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 

Similar to Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011

Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoMasahiro Nagano
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Masahiro Nagano
 
R57shell
R57shellR57shell
R57shellady36
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionAdam Trachtenberg
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7chuvainc
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6garux
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked aboutTatsuhiko Miyagawa
 
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014Amazon Web Services
 
Desarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesDesarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesLuis Curo Salvatierra
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012D
 
Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday DeveloperRoss Tuck
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなしMasahiro Honma
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Designunodelostrece
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeMongoDB
 

Similar to Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011 (20)

Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
PHP Tips & Tricks
PHP Tips & TricksPHP Tips & Tricks
PHP Tips & Tricks
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
 
R57shell
R57shellR57shell
R57shell
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
 
Desarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesDesarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móviles
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
Database api
Database apiDatabase api
Database api
 
Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday Developer
 
Php
PhpPhp
Php
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
 
R57.Php
R57.PhpR57.Php
R57.Php
 
Php functions
Php functionsPhp functions
Php functions
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 

More from Masahiro Nagano

Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/MinAdvanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/MinMasahiro Nagano
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Masahiro Nagano
 
Big Master Data PHP BLT #1
Big Master Data PHP BLT #1Big Master Data PHP BLT #1
Big Master Data PHP BLT #1Masahiro Nagano
 
Stream processing in Mercari - Devsumi 2015 autumn LT
Stream processing in Mercari - Devsumi 2015 autumn LTStream processing in Mercari - Devsumi 2015 autumn LT
Stream processing in Mercari - Devsumi 2015 autumn LTMasahiro Nagano
 
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月Masahiro Nagano
 
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015Masahiro Nagano
 
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LTNorikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LTMasahiro Nagano
 
メルカリでのNorikraの活用、 Mackerelを添えて
メルカリでのNorikraの活用、 Mackerelを添えてメルカリでのNorikraの活用、 Mackerelを添えて
メルカリでのNorikraの活用、 Mackerelを添えてMasahiro Nagano
 
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LTGazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LTMasahiro Nagano
 
Mackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LTMackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LTMasahiro Nagano
 
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術Masahiro Nagano
 
Isucon makers casual talks
Isucon makers casual talksIsucon makers casual talks
Isucon makers casual talksMasahiro Nagano
 
blogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べblogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べMasahiro Nagano
 
Gazelle - Plack Handler for performance freaks #yokohamapm
Gazelle - Plack Handler for performance freaks #yokohamapmGazelle - Plack Handler for performance freaks #yokohamapm
Gazelle - Plack Handler for performance freaks #yokohamapmMasahiro Nagano
 
Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014
Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014
Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014Masahiro Nagano
 
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LTWeb Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LTMasahiro Nagano
 
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版Masahiro Nagano
 
Webアプリケーションの パフォーマンス向上のコツ 実践編
 Webアプリケーションの パフォーマンス向上のコツ 実践編 Webアプリケーションの パフォーマンス向上のコツ 実践編
Webアプリケーションの パフォーマンス向上のコツ 実践編Masahiro Nagano
 
Webアプリケーションの パフォーマンス向上のコツ 概要編
 Webアプリケーションの パフォーマンス向上のコツ 概要編 Webアプリケーションの パフォーマンス向上のコツ 概要編
Webアプリケーションの パフォーマンス向上のコツ 概要編Masahiro Nagano
 
Webアプリケーションとメモリ
WebアプリケーションとメモリWebアプリケーションとメモリ
WebアプリケーションとメモリMasahiro Nagano
 

More from Masahiro Nagano (20)

Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/MinAdvanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
Big Master Data PHP BLT #1
Big Master Data PHP BLT #1Big Master Data PHP BLT #1
Big Master Data PHP BLT #1
 
Stream processing in Mercari - Devsumi 2015 autumn LT
Stream processing in Mercari - Devsumi 2015 autumn LTStream processing in Mercari - Devsumi 2015 autumn LT
Stream processing in Mercari - Devsumi 2015 autumn LT
 
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
 
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
 
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LTNorikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
 
メルカリでのNorikraの活用、 Mackerelを添えて
メルカリでのNorikraの活用、 Mackerelを添えてメルカリでのNorikraの活用、 Mackerelを添えて
メルカリでのNorikraの活用、 Mackerelを添えて
 
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LTGazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
 
Mackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LTMackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LT
 
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
ISUCON4 予選問題で(中略)、”my.cnf”に1行だけ足して予選通過ラインを突破するの術
 
Isucon makers casual talks
Isucon makers casual talksIsucon makers casual talks
Isucon makers casual talks
 
blogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べblogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べ
 
Gazelle - Plack Handler for performance freaks #yokohamapm
Gazelle - Plack Handler for performance freaks #yokohamapmGazelle - Plack Handler for performance freaks #yokohamapm
Gazelle - Plack Handler for performance freaks #yokohamapm
 
Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014
Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014
Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014
 
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LTWeb Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
 
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
 
Webアプリケーションの パフォーマンス向上のコツ 実践編
 Webアプリケーションの パフォーマンス向上のコツ 実践編 Webアプリケーションの パフォーマンス向上のコツ 実践編
Webアプリケーションの パフォーマンス向上のコツ 実践編
 
Webアプリケーションの パフォーマンス向上のコツ 概要編
 Webアプリケーションの パフォーマンス向上のコツ 概要編 Webアプリケーションの パフォーマンス向上のコツ 概要編
Webアプリケーションの パフォーマンス向上のコツ 概要編
 
Webアプリケーションとメモリ
WebアプリケーションとメモリWebアプリケーションとメモリ
Webアプリケーションとメモリ
 

Recently uploaded

Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 

Recently uploaded (20)

Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 21. sub logf { my ($level,$message) = @_; my ($pkg,$file,$line) = caller; my @time = localtime; warn sprintf "%04d-%02d-%02dT%02d:%02d:%02d [%s] %s at %s line %d.n", $time[5]+1900, $time[4]+1, @time[3,2,1,0], $level, $message, $file, $line; } logf(“WARN”,”timeout”); logf(“INFO”,”foo bar”); 2011-10-05T09:41:30 [WARN] timeout at test.pl line 10. 2011-10-05T09:41:30 [INFO] foo bar at test.pl line 11.
  • 22.
  • 23.
  • 24. 2011-10-05T09:41:30 [WARN] [/entry/foobar] failed request: http://ad.net/ read timeout at /path/to/Controler/Entry.pm line 10.
  • 25.
  • 26.
  • 27.
  • 28. use Log::Minimal; # stack trace debugf(‘blah blah blah’); infof(“server start $$”); critf("%s","foo"); warnf("%d %s", 1, "foo"); # stack trace debugff(‘blah blah blah’); infoff(“server start $$”); critff("%s","foo"); warnff("%d %s", 1, "foo");
  • 29. use Log::Minimal; debugf(‘blah blah blah’); # local $ENV{LM_DEBUG} = 1; debugf(‘blah blah blah’); # 2011-10-05T09:41:30 [DEBUG] blah.. at test.pl line 11.
  • 30. # local $Log::Minimal::PRINT = sub { my ( $time, $type, $message, $trace) = @_; warn(“$time [$type] $message $tracen”); }; # open( my $fh, ">>", "app.log"); local $Log::Minimal::PRINT = sub { my ( $time, $type, $msg, $tr, $r_msg ) = @_; print $fh “$time [$type] $r_msg $trn”; };
  • 31. # local $Log::Minimal::AUTODUMP = 1; warnf(“response => %s”,$res); 2011-05-11T15:56:14 [WARN] response => [200, ['Content-Type','text/plain'],['OK']] at .. # local $Log::Minimal::COLOR = 1; warnf(“hirose31”); 2011-05-11T15:56:14 [WARN] hirose31 at ..
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37. use Log::Minimal; use Plack::Builder; builder {     enable "Log::Minimal", autodump => 1;     sub {         my $env = shift;         warnf("warn");         debugf("debug");         ...     } }; $ plackup -a demo.psgi 2011-05-11T16:32:24 [WARN] [/foo/bar/baz] warn at /tmp/ demo.psgi line 8 2011-05-11T16:32:24 [DEBUG] [/foo/bar/baz] debug at /tmp/ demo.psgi line 9
  • 38. use Log::Minimal; use Parallel::Prefork; my $pm = Parallel::Prefork->new(); while ( $pm->signal_received ne 'TERM' ) { $pm->start(sub { local $Log::Minimal::AUTODUMP = 1; local $Log::Minimal::COLOR = 1; while (1) { my $job = $queue->dequeue; local $Log::Minimal::PRINT = sub { my ( $time, $type, $message, $trace) = @_; warn(“$$ [“,$job->name,”] [$type] $message $trace”); }; ... } }); }
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44. SELECT * FROM entries WHERE created_at >= '2011-10-05 00:00:00' AND created_at < '2011-10-06 00:00:00' AND status != 0; Data::Entry->search({ -and => [ created_at => {'>=','2011-10-05 00:00:00' }, created_at => {'<','2011-10-06 00:00:00' }, ], status => { '!=', 0 } });
  • 45. SELECT * FROM entries WHERE created_at >= '2011-10-05 00:00:00' AND created_at < '2011-10-06 00:00:00' AND status != 0; Data::Entry->search({ -and => [ created_at => {'>=','2011-10-05 00:00:00' }, created_at => {'<','2011-10-06 00:00:00' }, ], status => { '!=', 0 } });
  • 46. SELECT * FROM entries WHERE created_at >= '2011-10-05 00:00:00' AND created_at < '2011-10-06 00:00:00' AND status != 0; Data::Entry->search({ -and => [ created_at => {'>=','2011-10-05 00:00:00' }, created_at => {'<','2011-10-06 00:00:00' }, ], status => { '!=', 0 } });
  • 47.
  • 48.
  • 49.
  • 50. my $dbh = DBIx::Sunny->connect( ‘dsn’,‘user’,‘passwd’, ); ✓ RaiseError => 1 ✓ PrintError= > 0 ✓ ShowErrorStatement => 1 ✓ AutoInactiveDestroy => 1 ✓ sqlite_unicode/mysql_enable_utf8 => 1 ✓ mysql_auto_reconnect => 0
  • 51. my $sth = $dbh->prepare(“SELECT * FROM entries WHERE ..”); SELECT /* test.pl line 941 */ * FROM entries WHERE ..
  • 52. selectrow_arrayref($query, {}, @bind); selectrow_hashref($query, {}, @bind); selectall_arrayref($query, { Slice => {} }, @bind); prepare($query) && execute(@bind)
  • 53. my $builder = SQL::Maker->new( driver => 'mysql', ); my $dbh = DBIx::Sunny->connect(...); my ($sql, @binds) = $builder->select( 'user', ['*'], {name => 'john'}, {order_by => 'user_id DESC'} ); my $rows = $dbh->select_row($sql,@binds);
  • 54.
  • 55. my $dbh = DBI->connect($dsn,$user,$pass,{...}); while ( my $job = $queue->dequeue ) { .... } my $DBH; sub get_dbh { $DBH ||= DBI->connect($dsn,$user,$pass,{...}); $DBH; } while ( my $job = $queue->dequeue ) { my $dbh = get_dbh(); .... } sub get_dbh { DBI->connect_cached($dsn,$user,$pass,{...}); } while ( my $job = $queue->dequeue ) { my $dbh = get_dbh(); .... }
  • 56. my $dbh = DBI->connect($dsn,$user,$pass,{...}); while ( my $job = $queue->dequeue ) { .... } my $DBH; sub get_dbh { $DBH ||= DBI->connect($dsn,$user,$pass,{...}); $DBH; } while ( my $job = $queue->dequeue ) { my $dbh = get_dbh(); .... } sub get_dbh { DBI->connect_cached($dsn,$user,$pass,{...}); } while ( my $job = $queue->dequeue ) { my $dbh = get_dbh(); .... }
  • 57. > SHOW PROCESSLIST; +--------+-------------+--------------------+---------+---------+-------+----------+------+ | Id | User | Host | db | Command | Time | State | Info | +--------+-------------+--------------------+---------+---------+-------+----------+------+ | 1 | system user | | NULL | Connect | 4851 | Wait... | NULL | | 2 | system user | | NULL | Connect | 1 | Has r... | NULL | | 235873 | www-slave | 10.0.xxx.39:33018 | cluster | Sleep | 8 | | NULL | | 278334 | www-slave | 10.0.xxx.39:37627 | cluster | Sleep | 1206 | | NULL | | 365403 | www-slave | 10.0.xxx.39:43957 | cluster | Sleep | 1259 | | NULL | | 378019 | www-slave | 10.0.xxx.39:45098 | cluster | Sleep | 138 | | NULL | | 397336 | www-slave | 10.0.xxx.39:48595 | cluster | Sleep | 377 | | NULL | | 404611 | www-slave | 10.0.xxx.206:60525 | cluster | Sleep | 44 | | NULL | | 405048 | www-slave | 10.0.xxx.206:60645 | cluster | Sleep | 119 | | NULL | | 405091 | www-slave | 10.0.xxx.58:51982 | cluster | Sleep | 1104 | | NULL | ..... 811 rows in set (0.00 sec)
  • 58.
  • 59.
  • 60. my $sc = start_scope_container(); # scope_container(‘key1’,‘value1’); $value = scope_container(‘key1’); #value sub hoge { scope_container(‘key2’,‘foobar’); } { my $sc2 = start_scope_container(); # $value = scope_container(‘key1’); #value scope_container(‘key1’,‘blahblah’); hoge(); $value = scope_container(‘key1’); #blahblah $value = scope_container(‘key2’); #foobar undef $sc2; } $value = scope_container(‘key1’); #value $value = scope_container(‘key2’); #undefined
  • 61. my %DATA; # $DATA{'key1'} = 'value1'; $value = $DATA{'key1'} #value sub hoge { $DATA{'key2'} = 'foobar'; } { local %DATA; # $value = $DATA{'key1'} #value $DATA{'key1'} = ‘blahblah’ hoge(); $value = $DATA{'key1'}; #blahblah $value = $DATA{'key2'} #foobar } $value = $DATA{'key1'}; #value $value = $DATA{'key2'}; #undefined
  • 62. sub get_dbh { my $dsn = shift my $cache = scope_container($dsn); reutrn $cache if $cache; my $dbh = DBIx:Sunny->connect($dsn,$user,$pass); scope_container($dsn, $dbh); return $dbh; } while ( my $job = $queue->dequeue ) { my $sc = start_scope_container(); my $dbh = get_dbh(); #new connection my $dbh2 = get_dbh(); #cached .. # disconnect }
  • 63. use Scope::Container; use Scope::Container::DBI; sub get_dbh { Scope::Container::DBI->connect($dsn,$user,$pass,{}): } for my $id (1..$max) { my $sc = start_scope_container(); get_dbh()->do(...); #new connection get_dbh()->select_row(...); #cache undef $sc; # }
  • 64. # DBI local $Scope::Container::DBI::DBI_CLASS = “Amon2::DBI”; my $dbh = Scope::Container::DBI->connect( $dsn,$user,$pass,{}); # slave 1 my $dbh = Scope::Container::DBI->connect( [$dsn1,$user,$pass,{}], [$dsn2,$user,$pass,{}], [$dsn3,$user,$pass,{}], );
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70. use Plack::Builder; builder { enable “Scope::Container”; $app; }; # Plack::Middleware::Scope::Container sub call { my ( $self, $env) = @_; my $container = start_scope_container(); $self->app->($env); }
  • 71.
  • 72.
  • 73. key1 key2 key3 key4 key5 key6 key7 key8 key9 memcached1 memcached2 memcached3
  • 74. key1 key2 key3 key4 key5 key6 key7 key8 key9 memcached1 memcached2 memcached3
  • 75. key1 key2 key3 key4 key5 key6 key7 key8 key9 memcached1 memcached2 memcached3
  • 76. key1 key2 key3 key4 key5 key6 key7 key8 key9 memcached1 memcached2 memcached3
  • 77. App App mem DB
  • 78. App App App App mem DB mem
  • 79. App App App App mem DB mem DB
  • 80.
  • 81. use Cache::Memcached::IronPlate; use Cache::Memcached::Fast; my $memd = Cache::Memcached::IronPlate->new( cache => Cache::Memcached::Fast->new(...), ); $memd->get $memd->get_multi $memd->set $memd->add $memd->replace $memd->append $memd->prepend $memd->incr $memd->counter $memd->decr $memd->delete
  • 82. set(‘key:dup’,val,exp) get(‘key:dup’) IronPlate IronPlate set key:dist:{1..3} get key:dist:{1..3} mem1 mem2 mem3 mem1 mem2 mem3
  • 83. set(‘key:dist’,val,exp) get(‘key:dist’) IronPlate IronPlate set key:dist:{1..30} get key:dist:rand(30) mem1 mem2 mem3 mem1 mem2 mem3
  • 84. use Cache::Isolator; use Cache::Memcached::Fast;   my $isolator = Cache::Isolator->new(     cache => Cache::Memcached::Fast->new(...), ); $isolator->get(key); $isolator->set(key,val,expires);
  • 85. set(‘key’,val,30) set(‘key’,val,30) Isolator Isolator set key 30 set key:earlyexp 20 mem1 mem2 mem1 mem2
  • 86. use Cache::Isolator; use Cache::Memcached::Fast;   my $isolator = Cache::Isolator->new(     cache => Cache::Memcached::Fast->new(...), early_expires_ratio => 10, expires_before => 10 ); $isolator->get(key); $isolator->set(key,val,expires);
  • 87. use Cache::Isolator; use Cache::Memcached::Fast;   my $isolator = Cache::Isolator->new(     cache => Cache::Memcached::Fast->new(...),     concurrency => 3, ); $isolator->get_or_set(key, sub { my $dbh = get_dbh(); $dbh->select_all(heavy_sql); }, expires);
  • 88. DB response memcached
  • 89. DB response memcached
  • 90. DB response memcached
  • 91. DB response memcached
  • 92. DB response memcached
  • 93. DB response memcached
  • 94. DB response memcached
  • 95. DB response memcached
  • 96. DB response memcached
  • 97. DB response memcached
  • 98. DB response memcached
  • 99. DB response memcached
  • 100.
  • 101.
  • 102.
  • 103.
  • 104. use Plack::Builder; use File::Temp; builder { enable "ServerStatus::Lite", path => '/___server-status', allow => [‘127.0.0.1’,‘192.168.0.0/16’], scoreboard => File::Temp::tempdir(CLEANUP => 1); $app };
  • 105. $ curl http://localhost:5000/___server-status Uptime: 1318372692 BusyWorkers: 3 IdleWorkers: 27 -- pid status remote_addr host method uri protocol 1522 A 127.0.0.1 localhost:5000 GET /___server-status HTTP/1.1 1523 _ 192.168.67.3 192.168.67.4:5000 GET /foo/bar HTTP/1.0 1526 _ 192.168.67.5 192.168.67.4:5000 GET /foo/bar HTTP/1.0 ...
  • 106. use Parallel::Prefork; use Parallel::Scoreboard; my $sb = Parallel::Scoreboard->new( base_dir => ‘/var/run/example_worker’ ); my $pm = Parallel::Prefork->new({...}); while ( $pm->signal_received !~ m!^(?:TERM|INT)$! ) { $pm->start(sub{ $sb->update('.'); while(1) { my $job = $queue->dequeue; $sb->update('A'); #work work work $sb->update('.'); } }); }
  • 107. use Parallel::Prefork; use Parallel::Scoreboard; my $sb = Parallel::Scoreboard->new( base_dir => ‘/var/run/example_worker’ ); my $pm = Parallel::Prefork->new({...}); while ( $pm->signal_received !~ m!^(?:TERM|INT)$! ) { $pm->start(sub{ idle $sb->update('.'); while(1) { my $job = $queue->dequeue; $sb->update('A'); #work work work busy $sb->update('.'); } }); idle }
  • 108. # scoreboard.psgi my $sb = Parallel::Scoreboard->new( base_dir => ‘/var/run/example_worker’ ); sub { my $env = shift; my $stats = $scoreboard->read_all(); my $busy = 0; my $idle = 0; for my $pid ( sort { $a <=> $b } keys %$stats) { if ( $stats->{$pid} =~ m!^A! ) { $busy++; } else { busy $idle++; } } return [200,['Content-Type'=>'plain/text'], ["BusyWorkers: $busynIdleWorkers: $idle"]]; };
  • 109. # $ plackup -p 5001 -a scoreboard.psgi # $ curl http://localhost:5001/___server-status BusyWorkers: 6 IdleWorkers: 4
  • 110.
  • 111. 192.188.67.2 idle busy

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n