SlideShare a Scribd company logo
1 of 33
Download to read offline
Object::Franger


 Wear a Raincoat
  in Your Code


   Steven Lembark
 Workhorse Computing
Why do you need one?
●   Frankly, because you can't control your object:  
    you never know where it might end up.
    ●   Other people can fiddle with it.
    ●   Forks can leave it in unintended places.
    ●   It might get bugs (or worse).
    ●   External issues can require special handling.
Why an object wrapper?
●   All of the code required to handle all of the 
    special cases ends up bloating your work.
●   Most wrappers are re­usable: forks, timeouts, 
    and signals all use common code.
●   The division of labor isolates the wrapper and 
    inner portions into re­usable pieces.
●   All of which make these good fodder for OO.
Requirements for Wrappers.
●   They should feel like the real thing.
●   They cannot leak.
●   These are not easy: making the wrapper feel 
    enough like the real thing to fool both your 
    object and the caller.
Where wrappers can help.
●   Re­usable sanity checks (what goes on here).
●   Compatibility layers for changing API's.
●   Localizing values on the call stack.
●   Modifying context.
●   Simplifying the wrapped code, which doesn't 
    have to deal with all of this in one place.
    ●   Example: Top­ & Bottom­half device drivers.
Perly wrappers.
●   There is (of course) more than one way:
    ●   Override a method in a derived class.
    ●   Replace a method in the symbol table.
    ●   AUTOLOAD from stub namespace.
●   Example:
    ●   Attribute Handlers replace the subroutine before 
        it is installed (functional).
    ●   Object::Trampoline replaces the object in­place.
    ●   Object::Wraper (AUTOLOAD).
My particular itch: DBI with forks.
●   DBI objects cannot be re­cycled across forks.
●   I was writing heavily forked code for high­
    volume database access.
●   Needed the forks, needed the DBI to handle 
    the children gracefully.
●   Wanted child proc's to fail gracefully – 
    hopefully without damaging the database.
Why forks hurt DBI
●   The points are sharp.
●   Database connections use PID's to bookkeep 
    connections.
●   Servers cannot handle multiple clients requests 
    on the same channel.
●   Destroying an object in one process brings 
    kicks its longer­lived sibling in the socket.
Cleaning Up $dbh
●   Forked process:
    ●   Disable destroy side effects on the channel for 
        each object.
    ●   Iterate the handle and cached kids.
●   Within process:
    ●   Call $kid­>finish for all cached kids.
    ●   Call $dbh­>disconnect.
Cleaning up $dbh
                              my @kidz
                              = do
●   Extract the list of       {
                                  my $drh = $dbh->{ Driver };

    handles.                       my $list
                                   = $drh
                                   ? $drh->{ CachedKids }
●   If the process did not         : '';


    create them, then              $list
                                   ? values %$list
                                   : ()
    inactivate the            };

    DESTROY side effects.     if( $$ != $pid )
                              {
                                  $_->{ InactiveDestroy } = 1
●   Otherwise finish the      }
                                  for ( $dbh, @kidz );

                              else
    kids and then             {
                                  $_->finish for @kidz;
    disconnect.                    $dbh->disconnect;
                              }
Sanity checking a PID
●   Perl stores he current Process ID (“PID”) in  
    “$$” (i.e., looks like the shell variable).
●   Storing this when the handle is created allows 
    re­checking it before dispatching the call.
●   If the stored PID and $$ don't agree then the 
    handle needs to be cleaned up.
●   This has to be sanity­checked on method calls, 
    dealt with carefully in DESTROY.
Looks objective:
●   The code is re­usable.
    ●   All of the handles are cleaned up the same way.
    ●   All of the fork checks are the same.
    ●   All of the wrapping is done the same way.
●   It can be parameterized.
    ●   $$ is $$ wherever you are.
●   Frangers are good for objects.
My Requirements
●   These are called for every method in the 
    wrapped class: they have to be fast.
●   They also cannot use bulky storage since they 
    are add to the requirements for all wrapped 
    objects.
●   They should also avoid unintended side effects 
    (e.g., modifying object values, calling context).
O::W is built in layers.
●   Object::Wrapper base class provides generic 
    new, DESTROY, and an AUTOLOAD.
●   The AUTOLOAD calls sanity check hooks in 
    the derived classes and re­dispatches the result 
    or croaks.
●   Object::Wrapper::Fork bookkeeps $$.
●   Object::Wrapper::Fork::DBI deals with the 
    cleanups.
A Place to Hang Your Hat
●   A few hooks are all that's kneaded:
    ●   pre­dispatch for the sanity check.
    ●   straight­jacket for failed sanity checks.
●   These accommodate all of the necessary 
    customizations for the basic wrapper.
Throwing a Hook
●   Perl's “can” is rather helpful:
    ●   It returns true if the object “can”.
    ●   Its true value is a subref to the  object's handler.
●   This makes:
        my $handler = $object­>can( $hook );
        $object­>$handler­>( @argz );
    synonymous with:
        $handler­>( $object, @argz );
Structure of a Franger
●   Remember the need for speed, flexibility, and 
    encapsulation of the wrapped object.
●   Take a look at the calling standard: generic 
    object with arguments.
●   The structure is obvious:
      bless [ $object, @sanity_argz ], $class;
●   Resulting in:
      $handler->( @$obj );
Constructing a Franger
●   Store the call stack for validation as­is.

    sub new
    {
        my $proto   = shift;
        my $class   = blessed $proto || $proto;

        my $object = shift
        or croak "Bogus franger: missing object";

        bless [ $object, @_ ], $class
    }
OK, but what do you do with it?
●   Whatever you want.
●   Object::Wrapper, in fact, does nothing but re­
    dispatch the method calls.
●   Useful for cases where the interesting part of 
    the wrapper is in the DESTROY, not the 
    individual calls.
Wrapper AUTOLOAD is Standard
●   Does nothing more than necessary.
●   Useful when the DESTROY check is enogh.

AUTOLOAD
{
    my $franger = shift;

    my $i       = rindex $AUTOLOAD, ':';
    my $name    = substr $AUTOLOAD, ++$i;

    my $sub     = $franger->[0]->can( $name )
    or confess "Bogus $AUTOLOAD: '$franger->[0]' cannot '$name'";

    $franger->[0]->$sub( @_ )
}
Oedipus Not­Complex: Forks
AUTOLOAD
{
    my $franger = shift;
    my ( $obj, $pid ) = @$franger;

    $pid == $$
     or confess "Bogus $AUTOLOAD: @{$franger} crosses fork.";

    my $i       = rindex $AUTOLOAD, ':';
    my $name    = substr $AUTOLOAD, ++$i;

    my $sub     = $obj->can( $name )
    or confess "Bogus $AUTOLOAD: '$obj' cannot '$name'";

    # goto &$obj is slower according to Benchmark...

    $obj->$sub( @_ )
}
Clean Up Your Mess: O::W::Destroy
DESTROY
{
    my $franger = shift;

    my $class   = blessed $franger || $franger;

    # $cleanupz{ $class } may be a method name or coderef to save time.

    my $cleanup = $cleanupz{ $class } || $franger->can( 'cleanup' )
    or confess "Bogus franger: no cleanup for '$franger' or '$class'";

    my $sub
    = ref $cleanup
    ? $cleanup
    : $franger->can( $cleanup )
    or confess "Bogus $class: no cleanup for '$franger' ($class)";

    'CODE' eq reftype $sub
    or confess "Bogus $class: not a coderef '$sub'";

    $cleanup->( @$franger );

    return
}
DBI: It's All How You Clean Up
●   Check for cached_kids.
●   Within the constructing PID: 
    ●   Finish all the kids.
    ●   Disconnect the parent.
●   Within child Proc's:
    ●   Disable destroy side effects in the kids & parent.
First Step: Find the Kids
sub cleanup
{
    my ( $dbh, $pid ) = @_;

   my $struct
   = do
   {
        my $drh    = $dbh->{ Driver };

        $drh
        ? $drh->{ CachedKids }
        : ''
   };

   my @kidz
   = $struct
   ? values %$struct
   : ()
   ;
Second Step: Do the Deed

    if( $$ != $pid )
    {
        # handle crossed a fork: turn off side
        # effects of destruction.

        $_->{ InactiveDestroy } = 1
        for
        (
            $dbh,
            @kidz
        );
    }
    else
    {
        $_->finish for @kidz;

        $dbh->disconnect;
    }

    # at this point the DBI object has been
    # prepared to go out of scope politely.

    return
}
Cleaning Up Statements Is Easier
sub cleanup
{
    my ( $sth, $pid ) = @_;

    if( $$ ~~ $pid )
    {
        # same process: finalize the handle and disconnect.
        # caller deals with clones.

           $sth->{ Active }
           and $sth->finish;
    }
    else
    {
           $sth->{ InactiveDestroy } = 1;
    }

    # at this point the DBD object has been
    # prepared to go out of scope politely.

    return
}
Getting What You Want: 
Overloading Constructors
●   For DBI this requires versions of connect and 
    connect_cached, prepare and prepare_cached.
●   Connect simply returns the wrapped $dbh:
    sub connect
    {
        shift;

        my $dbh     = DBI->connect( @_ )
        or croak 'Fail connect: ' . $DBI::errstr;

        Object::Wrapper::Fork::dbh->new( $dbh )
    }
Overloading STH Constructors
●   These get a DBI wrapper object.
●   Returning a wrapped DBD.
    sub prepare
    {
        my $franger = shift;

        my ( $dbh, $pid ) = @$franger;

        $pid == $$
        or confess "Bogus prepare: @{ $franger } crosses fork.";

        my $sth = $dbh->prepare( @_ )
        or croak 'Failed prepare: ' . $dbh->errstr;

        Object::Wrapper::Fork::sth->new( $sth )
    }
Wrappers are not 100% effective
●   DBI offers a tied­hash interface.
●   Kinda hard to handle this with a blessed array.
●   Fortunately, the hash interface is rarely 
    necessary.
●   There is also one more issue for destructors.
Making Happy ENDings
●   Perl destroys objects out­of­order on exit.
●   This means that we also have to wrap 
    DBI::DESTROY to get complete coverage.
    ●   Fortunately this isn't all that hard to do with the 
        Symbol module's qualify_to_ref.
    ●   This requires a map of $dbh → O::W::F::DBI 
        objects that can be used to dispatch destruction.
    ●   No time to describe it here.
Other Uses for Object::Wrappers
●   Maximum time:
     bless [ $obj, ( time + $window ) ];
     time < $franger->[1] or ...
●   Maximum reuse:
     bless [ $obj, $counter ];
     --$franger->[1] or ...
Only Your Wrapper Knows For Sure
●   Long­lived processes may not want to die after 
     the wrapped object hits its limit.
●   Nice thing is that they don't have to:
      --$franger->[ 1 ]
      or @$franger = ( $class->new( ... ), $counter );
●   This is handy for classes with memory leaks in 
    the objects.
Summary
●   Keeping your object safe is easy:
    ●   Use a franger.
    ●   Check before you use it.
    ●   Make sure you clean up afterwards.

More Related Content

What's hot

Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Gonzalo Ayuso
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Wilson Su
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsClinton Dreisbach
 
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"ZendCon
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)brian d foy
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascriptDoeun KOCH
 
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESDrupalCamp Kyiv
 
AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.Yan Yankowski
 

What's hot (20)

Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Desymfony2013.gonzalo123
Desymfony2013.gonzalo123
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
SOLID Ruby SOLID Rails
SOLID Ruby SOLID RailsSOLID Ruby SOLID Rails
SOLID Ruby SOLID Rails
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Lecture 6: Client Side Programming 2
Lecture 6: Client Side Programming 2Lecture 6: Client Side Programming 2
Lecture 6: Client Side Programming 2
 
Lecture 5: Client Side Programming 1
Lecture 5: Client Side Programming 1Lecture 5: Client Side Programming 1
Lecture 5: Client Side Programming 1
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8
 
Javascript - Beyond-jQuery
Javascript - Beyond-jQueryJavascript - Beyond-jQuery
Javascript - Beyond-jQuery
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
Grails UI Primer
Grails UI PrimerGrails UI Primer
Grails UI Primer
 
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
 
Make it SOLID!
Make it SOLID!Make it SOLID!
Make it SOLID!
 
Entity api
Entity apiEntity api
Entity api
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
 
Object Features
Object FeaturesObject Features
Object Features
 
AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 

Viewers also liked

Raincoat survey findings
Raincoat survey findingsRaincoat survey findings
Raincoat survey findingspwally1234
 
Business plan (air umbrella)
Business plan (air umbrella)Business plan (air umbrella)
Business plan (air umbrella)are you
 
State of art
State of artState of art
State of artLa_Lu
 
認知症にやさしいまちづくり ~セクターを越えたつながり~
認知症にやさしいまちづくり ~セクターを越えたつながり~認知症にやさしいまちづくり ~セクターを越えたつながり~
認知症にやさしいまちづくり ~セクターを越えたつながり~Dementia Friendly Japan Initiative
 
BigWeatherGear Group and Corporate Services Brochure 2013
BigWeatherGear Group and Corporate Services Brochure 2013BigWeatherGear Group and Corporate Services Brochure 2013
BigWeatherGear Group and Corporate Services Brochure 2013Kristin Matson
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsLinkedIn
 
UX, ethnography and possibilities: for Libraries, Museums and Archives
UX, ethnography and possibilities: for Libraries, Museums and ArchivesUX, ethnography and possibilities: for Libraries, Museums and Archives
UX, ethnography and possibilities: for Libraries, Museums and ArchivesNed Potter
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerLuminary Labs
 
Designing Teams for Emerging Challenges
Designing Teams for Emerging ChallengesDesigning Teams for Emerging Challenges
Designing Teams for Emerging ChallengesAaron Irizarry
 
Visual Design with Data
Visual Design with DataVisual Design with Data
Visual Design with DataSeth Familian
 
3 Things Every Sales Team Needs to Be Thinking About in 2017
3 Things Every Sales Team Needs to Be Thinking About in 20173 Things Every Sales Team Needs to Be Thinking About in 2017
3 Things Every Sales Team Needs to Be Thinking About in 2017Drift
 
TEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of WorkTEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of WorkVolker Hirsch
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheLeslie Samuel
 

Viewers also liked (16)

Raincoat survey findings
Raincoat survey findingsRaincoat survey findings
Raincoat survey findings
 
Business plan (air umbrella)
Business plan (air umbrella)Business plan (air umbrella)
Business plan (air umbrella)
 
State of art
State of artState of art
State of art
 
認知症にやさしいまちづくり ~セクターを越えたつながり~
認知症にやさしいまちづくり ~セクターを越えたつながり~認知症にやさしいまちづくり ~セクターを越えたつながり~
認知症にやさしいまちづくり ~セクターを越えたつながり~
 
State of the Cloud 2017
State of the Cloud 2017State of the Cloud 2017
State of the Cloud 2017
 
Projeto gelo
Projeto geloProjeto gelo
Projeto gelo
 
BigWeatherGear Group and Corporate Services Brochure 2013
BigWeatherGear Group and Corporate Services Brochure 2013BigWeatherGear Group and Corporate Services Brochure 2013
BigWeatherGear Group and Corporate Services Brochure 2013
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving Cars
 
UX, ethnography and possibilities: for Libraries, Museums and Archives
UX, ethnography and possibilities: for Libraries, Museums and ArchivesUX, ethnography and possibilities: for Libraries, Museums and Archives
UX, ethnography and possibilities: for Libraries, Museums and Archives
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI Explainer
 
Designing Teams for Emerging Challenges
Designing Teams for Emerging ChallengesDesigning Teams for Emerging Challenges
Designing Teams for Emerging Challenges
 
Visual Design with Data
Visual Design with DataVisual Design with Data
Visual Design with Data
 
3 Things Every Sales Team Needs to Be Thinking About in 2017
3 Things Every Sales Team Needs to Be Thinking About in 20173 Things Every Sales Team Needs to Be Thinking About in 2017
3 Things Every Sales Team Needs to Be Thinking About in 2017
 
Build Features, Not Apps
Build Features, Not AppsBuild Features, Not Apps
Build Features, Not Apps
 
TEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of WorkTEDx Manchester: AI & The Future of Work
TEDx Manchester: AI & The Future of Work
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your Niche
 

Similar to Object Wrappers Protect Against Forks

Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
Perl Intro 7 Subroutines
Perl Intro 7 SubroutinesPerl Intro 7 Subroutines
Perl Intro 7 SubroutinesShaun Griffith
 
35 Years of Open Source Software
35 Years of Open Source Software35 Years of Open Source Software
35 Years of Open Source SoftwareFrancois Marier
 
Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)A K M Zahiduzzaman
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
 
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
 
Drush Productivity FTW - DUG @ Krimson
Drush Productivity FTW - DUG @ KrimsonDrush Productivity FTW - DUG @ Krimson
Drush Productivity FTW - DUG @ KrimsonKristof Van Roy
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Editionddiers
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Railselliando dias
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpMichael Girouard
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboardsDenis Ristic
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developersAndrew Eddie
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHPWim Godden
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Nikita Popov
 

Similar to Object Wrappers Protect Against Forks (20)

Lazy Data Using Perl
Lazy Data Using PerlLazy Data Using Perl
Lazy Data Using Perl
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
Perl Intro 7 Subroutines
Perl Intro 7 SubroutinesPerl Intro 7 Subroutines
Perl Intro 7 Subroutines
 
35 Years of Open Source Software
35 Years of Open Source Software35 Years of Open Source Software
35 Years of Open Source Software
 
Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)Optimizing a large angular application (ng conf)
Optimizing a large angular application (ng conf)
 
Magic methods
Magic methodsMagic methods
Magic methods
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
PHP Tips & Tricks
PHP Tips & TricksPHP Tips & Tricks
PHP Tips & Tricks
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Drush Productivity FTW - DUG @ Krimson
Drush Productivity FTW - DUG @ KrimsonDrush Productivity FTW - DUG @ Krimson
Drush Productivity FTW - DUG @ Krimson
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented Php
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?
 
Taming Command Bus
Taming Command BusTaming Command Bus
Taming Command Bus
 

More from Workhorse Computing

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWorkhorse Computing
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpWorkhorse Computing
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlWorkhorse Computing
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Workhorse Computing
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationWorkhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.Workhorse Computing
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Workhorse Computing
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 

More from Workhorse Computing (20)

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
Effective Benchmarks
Effective BenchmarksEffective Benchmarks
Effective Benchmarks
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Smoking docker
Smoking dockerSmoking docker
Smoking docker
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 

Recently uploaded

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Recently uploaded (20)

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 

Object Wrappers Protect Against Forks

  • 1. Object::Franger Wear a Raincoat in Your Code Steven Lembark Workhorse Computing
  • 2. Why do you need one? ● Frankly, because you can't control your object:   you never know where it might end up. ● Other people can fiddle with it. ● Forks can leave it in unintended places. ● It might get bugs (or worse). ● External issues can require special handling.
  • 3. Why an object wrapper? ● All of the code required to handle all of the  special cases ends up bloating your work. ● Most wrappers are re­usable: forks, timeouts,  and signals all use common code. ● The division of labor isolates the wrapper and  inner portions into re­usable pieces. ● All of which make these good fodder for OO.
  • 4. Requirements for Wrappers. ● They should feel like the real thing. ● They cannot leak. ● These are not easy: making the wrapper feel  enough like the real thing to fool both your  object and the caller.
  • 5. Where wrappers can help. ● Re­usable sanity checks (what goes on here). ● Compatibility layers for changing API's. ● Localizing values on the call stack. ● Modifying context. ● Simplifying the wrapped code, which doesn't  have to deal with all of this in one place. ● Example: Top­ & Bottom­half device drivers.
  • 6. Perly wrappers. ● There is (of course) more than one way: ● Override a method in a derived class. ● Replace a method in the symbol table. ● AUTOLOAD from stub namespace. ● Example: ● Attribute Handlers replace the subroutine before  it is installed (functional). ● Object::Trampoline replaces the object in­place. ● Object::Wraper (AUTOLOAD).
  • 7. My particular itch: DBI with forks. ● DBI objects cannot be re­cycled across forks. ● I was writing heavily forked code for high­ volume database access. ● Needed the forks, needed the DBI to handle  the children gracefully. ● Wanted child proc's to fail gracefully –  hopefully without damaging the database.
  • 8. Why forks hurt DBI ● The points are sharp. ● Database connections use PID's to bookkeep  connections. ● Servers cannot handle multiple clients requests  on the same channel. ● Destroying an object in one process brings  kicks its longer­lived sibling in the socket.
  • 9. Cleaning Up $dbh ● Forked process: ● Disable destroy side effects on the channel for  each object. ● Iterate the handle and cached kids. ● Within process: ● Call $kid­>finish for all cached kids. ● Call $dbh­>disconnect.
  • 10. Cleaning up $dbh my @kidz = do ● Extract the list of  { my $drh = $dbh->{ Driver }; handles. my $list = $drh ? $drh->{ CachedKids } ● If the process did not  : ''; create them, then  $list ? values %$list : () inactivate the  }; DESTROY side effects. if( $$ != $pid ) { $_->{ InactiveDestroy } = 1 ● Otherwise finish the  } for ( $dbh, @kidz ); else kids and then  { $_->finish for @kidz; disconnect. $dbh->disconnect; }
  • 11. Sanity checking a PID ● Perl stores he current Process ID (“PID”) in   “$$” (i.e., looks like the shell variable). ● Storing this when the handle is created allows  re­checking it before dispatching the call. ● If the stored PID and $$ don't agree then the  handle needs to be cleaned up. ● This has to be sanity­checked on method calls,  dealt with carefully in DESTROY.
  • 12. Looks objective: ● The code is re­usable. ● All of the handles are cleaned up the same way. ● All of the fork checks are the same. ● All of the wrapping is done the same way. ● It can be parameterized. ● $$ is $$ wherever you are. ● Frangers are good for objects.
  • 13. My Requirements ● These are called for every method in the  wrapped class: they have to be fast. ● They also cannot use bulky storage since they  are add to the requirements for all wrapped  objects. ● They should also avoid unintended side effects  (e.g., modifying object values, calling context).
  • 14. O::W is built in layers. ● Object::Wrapper base class provides generic  new, DESTROY, and an AUTOLOAD. ● The AUTOLOAD calls sanity check hooks in  the derived classes and re­dispatches the result  or croaks. ● Object::Wrapper::Fork bookkeeps $$. ● Object::Wrapper::Fork::DBI deals with the  cleanups.
  • 15. A Place to Hang Your Hat ● A few hooks are all that's kneaded: ● pre­dispatch for the sanity check. ● straight­jacket for failed sanity checks. ● These accommodate all of the necessary  customizations for the basic wrapper.
  • 16. Throwing a Hook ● Perl's “can” is rather helpful: ● It returns true if the object “can”. ● Its true value is a subref to the  object's handler. ● This makes: my $handler = $object­>can( $hook ); $object­>$handler­>( @argz ); synonymous with: $handler­>( $object, @argz );
  • 17. Structure of a Franger ● Remember the need for speed, flexibility, and  encapsulation of the wrapped object. ● Take a look at the calling standard: generic  object with arguments. ● The structure is obvious: bless [ $object, @sanity_argz ], $class; ● Resulting in: $handler->( @$obj );
  • 18. Constructing a Franger ● Store the call stack for validation as­is. sub new { my $proto = shift; my $class = blessed $proto || $proto; my $object = shift or croak "Bogus franger: missing object"; bless [ $object, @_ ], $class }
  • 19. OK, but what do you do with it? ● Whatever you want. ● Object::Wrapper, in fact, does nothing but re­ dispatch the method calls. ● Useful for cases where the interesting part of  the wrapper is in the DESTROY, not the  individual calls.
  • 20. Wrapper AUTOLOAD is Standard ● Does nothing more than necessary. ● Useful when the DESTROY check is enogh. AUTOLOAD { my $franger = shift; my $i = rindex $AUTOLOAD, ':'; my $name = substr $AUTOLOAD, ++$i; my $sub = $franger->[0]->can( $name ) or confess "Bogus $AUTOLOAD: '$franger->[0]' cannot '$name'"; $franger->[0]->$sub( @_ ) }
  • 21. Oedipus Not­Complex: Forks AUTOLOAD { my $franger = shift; my ( $obj, $pid ) = @$franger; $pid == $$ or confess "Bogus $AUTOLOAD: @{$franger} crosses fork."; my $i = rindex $AUTOLOAD, ':'; my $name = substr $AUTOLOAD, ++$i; my $sub = $obj->can( $name ) or confess "Bogus $AUTOLOAD: '$obj' cannot '$name'"; # goto &$obj is slower according to Benchmark... $obj->$sub( @_ ) }
  • 22. Clean Up Your Mess: O::W::Destroy DESTROY { my $franger = shift; my $class = blessed $franger || $franger; # $cleanupz{ $class } may be a method name or coderef to save time. my $cleanup = $cleanupz{ $class } || $franger->can( 'cleanup' ) or confess "Bogus franger: no cleanup for '$franger' or '$class'"; my $sub = ref $cleanup ? $cleanup : $franger->can( $cleanup ) or confess "Bogus $class: no cleanup for '$franger' ($class)"; 'CODE' eq reftype $sub or confess "Bogus $class: not a coderef '$sub'"; $cleanup->( @$franger ); return }
  • 23. DBI: It's All How You Clean Up ● Check for cached_kids. ● Within the constructing PID:  ● Finish all the kids. ● Disconnect the parent. ● Within child Proc's: ● Disable destroy side effects in the kids & parent.
  • 24. First Step: Find the Kids sub cleanup { my ( $dbh, $pid ) = @_; my $struct = do { my $drh = $dbh->{ Driver }; $drh ? $drh->{ CachedKids } : '' }; my @kidz = $struct ? values %$struct : () ;
  • 25. Second Step: Do the Deed if( $$ != $pid ) { # handle crossed a fork: turn off side # effects of destruction. $_->{ InactiveDestroy } = 1 for ( $dbh, @kidz ); } else { $_->finish for @kidz; $dbh->disconnect; } # at this point the DBI object has been # prepared to go out of scope politely. return }
  • 26. Cleaning Up Statements Is Easier sub cleanup { my ( $sth, $pid ) = @_; if( $$ ~~ $pid ) { # same process: finalize the handle and disconnect. # caller deals with clones. $sth->{ Active } and $sth->finish; } else { $sth->{ InactiveDestroy } = 1; } # at this point the DBD object has been # prepared to go out of scope politely. return }
  • 27. Getting What You Want:  Overloading Constructors ● For DBI this requires versions of connect and  connect_cached, prepare and prepare_cached. ● Connect simply returns the wrapped $dbh: sub connect { shift; my $dbh = DBI->connect( @_ ) or croak 'Fail connect: ' . $DBI::errstr; Object::Wrapper::Fork::dbh->new( $dbh ) }
  • 28. Overloading STH Constructors ● These get a DBI wrapper object. ● Returning a wrapped DBD. sub prepare { my $franger = shift; my ( $dbh, $pid ) = @$franger; $pid == $$ or confess "Bogus prepare: @{ $franger } crosses fork."; my $sth = $dbh->prepare( @_ ) or croak 'Failed prepare: ' . $dbh->errstr; Object::Wrapper::Fork::sth->new( $sth ) }
  • 29. Wrappers are not 100% effective ● DBI offers a tied­hash interface. ● Kinda hard to handle this with a blessed array. ● Fortunately, the hash interface is rarely  necessary. ● There is also one more issue for destructors.
  • 30. Making Happy ENDings ● Perl destroys objects out­of­order on exit. ● This means that we also have to wrap  DBI::DESTROY to get complete coverage. ● Fortunately this isn't all that hard to do with the  Symbol module's qualify_to_ref. ● This requires a map of $dbh → O::W::F::DBI  objects that can be used to dispatch destruction. ● No time to describe it here.
  • 31. Other Uses for Object::Wrappers ● Maximum time: bless [ $obj, ( time + $window ) ]; time < $franger->[1] or ... ● Maximum reuse: bless [ $obj, $counter ]; --$franger->[1] or ...
  • 32. Only Your Wrapper Knows For Sure ● Long­lived processes may not want to die after   the wrapped object hits its limit. ● Nice thing is that they don't have to: --$franger->[ 1 ] or @$franger = ( $class->new( ... ), $counter ); ● This is handy for classes with memory leaks in  the objects.
  • 33. Summary ● Keeping your object safe is easy: ● Use a franger. ● Check before you use it. ● Make sure you clean up afterwards.