SlideShare une entreprise Scribd logo
1  sur  216
Télécharger pour lire hors ligne
Reflex
How does it work?
   Rocco Caputo – @rcaputo
          YAPC::NA
     Tuesday, 28 June 2011
        Around Teatime
Feedback, plx.
This talk
describes the
Github Version
Who Does He Think He Is?


• Rocco Caputo or “rcaputo” most places.
 • http://search.cpan.org/~rcaputo/
 • https://github.com/rcaputo
 • http://twitter.com/rcaputo
“The POE Guy”
⃠
“The POE Guy”
Curtis “Ovid”
    Poe
Edgar
Allan
 Poe
Anne
 Decatur
Danielewski
The Other Committers
•   Adam Kennedy            •   Jonathan Steinert

•   Benjamin Smith          •   Larwan Berke

•   Casey West              •   Martijn van Beers

•   Chris Fedde             •   Matt Cashner

•   Chris Williams          •   Matt Sickler

•   David Davis             •   Perl Whore

•   David Webb              •   Philip Gwyn

•   Hinrik Örn Sigurðsson   •   Tom Feist

•   jmadler                 •   Yuval Kogman
The CPAN Authors
Alejandro Imass • Alessandro Ranellucci • Anatoly Sharifulin • Andrew A.
Chen • Andrew Hoying • Andrew Sterling Hanenkamp • Andrew V. Purshottam •
Andy Grundman • Artur Bergman • Benjamin Trott • Brendan Beveridge •
Chris Cobb • Chris Prather • Christian-Rolf Gruen • Curtis Hawthorne •
Daisuke Maki • Daisuke Murase • Damien Krotkine • Dan McCormick • David
Golden • David Snopek • Denis Pokataev • Dmitry Karasik • dmitry kim •
Eriam Schaffter • Eric Waters • Erick Calder • George Nistorica • Greg
Fast • Guillermo Roditi • Hans Dieter Pearcey • Ivan B. Serezhkin • J. J.
Merelo Guervos • Jan Henning Thorsen • Jason McManus • Jeff Bisbee • Jeff
Goff • Jerome Quelin • Johannes Plunien • Jonathan Ringstad • Jozef Kutej
• Justin Hunter • Kazuhiro Osawa • Kevin L. Esteb • Kirill Miazine •
Larry Shatzer Jr • Loic TROCHET • Marc Lehmann • Marc Mims • Mark A.
Hershberger • Mark McConnell • Mark Morgan • Markus Mueller • Matthew
O’Connor • Michael Ching • Michael R. Davis • Michael Schilli • Mike
Fletcher • Mike Schroeder • Mischa Spiegelmock • MOCK • MSERGEANT •
Nicholas Perez • Olivier ‘dolmen’ Mengue • Paul David Tinsley • Paul
Driver • Paul Evans • Paul G Webster • Paul Visscher • Pavel Boldin •
Pedro Melo • Peter Guzis • Przemyslaw Iskra • Rafael Kitover • Richard
Clamp • Rob Bloodgood • Rob Partington • Robert ‘phaylon’ Sedlacek •
Sawyer X • Scott Beck • Scott McCoy • Sean Egan • Sebastien Aperghis-
Tramoni • Sergey Kotenko • Sergey Skvortsov • Sjors Gielen • Stephen
Adkins • Steve James • Steve McNabb • Takeshi Miki • Tatsuhiko Miyagawa •
Thiago Berlitz Rondon • Tony Cook • Torsten Raudssus • wb@95700.net •
William Travis Holton • Yuji Suzuki • Yves Blusseau • Zoffix Znet
The Users

EOVERFLOW
Okay, me too.
Digression:
See Digression
Reflex
What Is It?
Rocco Caputo – @rcaputo
       YAPC::NA
  Tuesday, 28 June 2011
     Around Teatime
Reflex
What Isn’t It?
Rocco Caputo – @rcaputo
       YAPC::NA
  Tuesday, 28 June 2011
     Around Teatime
What can’t you do with
  a drunken sailor?
Reflex is an only
 child waiting in
    the park.
⃠
Reflex is an only
 child waiting in
    the park.
Reflex isn’t an
 event loop.
CPAN
already has
 too many
    event
   loops.
Event loops
are the means,
 not the ends.
Reflex is
eventy without
so much loopy.
Nor is Reflex an
 object system.
CPAN
already has
 too many
   object
  systems.
Reflex uses
  Moose
But Why?!
“I am disappointed that after all this
time we have no consensus on how
to say in Perl ‘Class X has attribute
Y’ when so many other languages
have solutions that have freed their
users’ minds up to move on to
higher-level problems.”
— Peter Scott, on the Perl 5 Porters Mailing List
But Why?!

• Moose lets me solve higher-level problems.
• Moose has sufficient adoption to survive.
• The Meta-Object Protocol is insanely useful.
• Moose will get better as native Perl OO
  improves.
Reflex
What Is It?
Rocco Caputo – @rcaputo
       YAPC::NA
  Tuesday, 28 June 2011
     Around Teatime
The ORM of
Event Loops!!
Marketing
bullshit aside...
Reactive
Program Building
     Blocks
Building
 Blocks
Provided
by Moose
Plus a Reactor
provided by Your
 Favorite Event
      Loop
Invisible Event Loop
Like ORMs
 hide SQL     ORM

  behind
 objects...   DB
Reflex
hides event
   loops      Reflex


  behind       The
              Events

 objects...    Can
Reflex is
Modern
 POE
Reflex is Modern POE
• POE = Perl Object Environment
• Modern Perl objects are very different than
  1998 Perl objects.
• POE has a lot of users.
• Start over with Reflex so POE remains
  compatible.
Reflex
   unifies
   eventy
interaction.
Rule 34 for Perl

If you can think
of it, CPAN has
a module for it.
TIMTOWTDI
If you can think
of it, CPAN has
2+ incompatible
modules for it...
TIMTOWTDI

 ... and someday
  you’ll need to
use both at once.
TIMTOWTDI

• There’s more than one way to pass
  events around.
• The “best” way... depends.
• Choosing poorly limits later options.
• Reflex supports any or all at once.
3 ½ Rules
Make it Work
⁓1⁓
Objects must not
 dictate callback
  mechanisms.
⁓ 1.5 ⁓
  Users define
    how they
receive callbacks.
⁓2⁓
The base system
must support all
desired callback
     types.
⁓3⁓
 Reflex must do
just enough work
   to be correct.
Reflex unifies
eventy program
 composition.
“How Eventy
Programs are
Put Together”
Static Composition

• Code is bolted together before running.
 • Subclassing.
 • Role composition.
• All pieces built and destroyed together.
• Most eventy abstractions ignore this.
Dynamic Composition

• Event watchers are created,
 • related (has-a),
   • communicated (with),
     • and destructicated
       • at run time.
• Lather, rinse, repeat until the owner ends.
Dynamic Lifetimes
• Object provides service to one owner.
 • Object life is briefer than its owner.
 • Object’s lifespan matches its owner.
   • Good candidate for static composition.
• Object provides service to 2+ subscribers.
 • Good candidate for breadboarding or
    publish/subscribe.
Reflex
  Embraces,
 Extends and
Consumes Both
Examples are
   next.
Reflex
How to Use It!
 Rocco Caputo – @rcaputo
        YAPC::NA
   Tuesday, 28 June 2011
      Around Teatime
Anonymous
 Callbacks
Ye Olde Coderef
    use Reflex::Interval;

•   my $i_one = Reflex::Interval->new(
•      interval => 1,
       on_tick => sub { print "tick one...n" },
    );

    my $i_two = Reflex::Interval->new(
       interval => 0.5,
       on_tick => sub { print "tick two...n" },
    );

    Reflex->run_all();
Ye Olde Coderef
    use Reflex::Interval;

    my $i_one = Reflex::Interval->new(
       interval => 1,
•      on_tick => sub { print "tick one...n" },
    );

    my $i_two = Reflex::Interval->new(
       interval => 0.5,
       on_tick => sub { print "tick two...n" },
    );

    Reflex->run_all();
Ye Olde Coderef
    use Reflex::Interval;

    my $i_one = Reflex::Interval->new(
       interval => 1,
       on_tick => sub { print "tick one...n" },
    );

•   my $i_two = Reflex::Interval->new(
•      interval => 0.5,
       on_tick => sub { print "tick two...n" },
    );

    Reflex->run_all();
Ye Olde Coderef
    use Reflex::Interval;

    my $i_one = Reflex::Interval->new(
       interval => 1,
       on_tick => sub { print "tick one...n" },
    );

    my $i_two = Reflex::Interval->new(
       interval => 0.5,
•      on_tick => sub { print "TICK TWO!!!n" },
    );

    Reflex->run_all();
Ye Olde Coderef
tick   one...
TICK   TWO!!!
TICK   TWO!!!
tick   one...
TICK   TWO!!!
TICK   TWO!!!
tick   one...
TICK   TWO!!!
TICK   TWO!!!
^C
Ye Olde Coderef - The Good


• Quick and dead simple to use.
• Convenient and fast for small things.
• Parsimonious use of memory.
Ye Olde Coderef - The Bad

• Circular references and memory leaks—
  unless you explicitly manage memory.
• Anti-pattern if done solely for speed...
 • Implementation detail wags the dog.
 • Giving up OO benefits for speed.
Ye Olde Coderef - The Ugly
 # A twisty maze of coderefs, all alike.

 Watcher( sub {
   Watcher( sub {
     Watcher( sub {
       Watcher( sub {
         Watcher( sub {
           Watcher( sub {
             Watcher( sub {
                Watcher( sub {
                  Watcher( sub {
                    Watcher( sub {
                      Watcher( sub {
                        Watcher( sub {
Method
Callbacks
Method Callbacks
    {
•       package TickingThing;
•       use Moose; extends "Reflex::Base";
        use Reflex::Interval;

        has ticker => (
           isa => "Reflex::Interval", is => "rw",
          default => sub {
              my $self = shift();
              Reflex::Interval->new(
                interval => 1, on_tick => [ $self, "callback" ],
              )
           },
        );

        sub callback { print "method got tick...n" }
    }

    Thing->new()->run_all();
Method Callbacks
    {
        package TickingThing;
        use Moose; extends "Reflex::Base";
        use Reflex::Interval;

•       has ticker => (
•          isa => "Reflex::Interval", is => "rw",
          default => sub {
              my $self = shift();
              Reflex::Interval->new(
                interval => 1, on_tick => [ $self, "callback" ],
              )
           },
        );

        sub callback { print "method got tick...n" }
    }

    Thing->new()->run_all();
Method Callbacks
    {
        package TickingThing;
        use Moose; extends "Reflex::Base";
        use Reflex::Interval;

        has ticker => (
           isa => "Reflex::Interval", is => "rw",
           default => sub {
              my $self = shift();
              Reflex::Interval->new(
•              interval => 1, on_tick => [ $self, "callback" ],
              )
           },
        );

        sub callback { print "method got tick...n" }
    }

    Thing->new()->run_all();
Method Callbacks
    {
        package TickingThing;
        use Moose; extends "Reflex::Base";
        use Reflex::Interval;

        has ticker => (
           isa => "Reflex::Interval", is => "rw",
           default => sub {
              my $self = shift();
              Reflex::Interval->new(
•               interval => 1, on_tick => [ $self, "callback" ],
              )
           },
        );

•       sub callback { print "method got tick...n" }
    }

    Thing->new()->run_all();
Method Callbacks
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
method   got   tick...
^C
Methods – The Costs

• Verbose syntax.
• Perl OO is slower than code references
  and closures.
• Perl OO requires memory.
• Moose uses memory, too.
Methods – The Benefits
• Syntax gets sweeter.
• Object oriented design is cleaner and more
  extensible.
  • No twisty maze of nested code
    references, all different.
• It’s all “standard” Perl and/or Moose.
Methods – The Future

• Avoiding flexibility by design is a dead end.
• Speed and size improve over time.
• Perl may get its own MOP.
 • Moose and Moose-alikes may converge as
    Perl standardizes common features.
“But callbacks
suck!” you say?
Promises
What’s a Promise?

“an object that acts as a proxy
for a result that is initially not
known, usually because the
computation of its value has not
yet completed.”
                        — Wikipedia
What’s a Promise?


Blah, blah, blah.
Promises
• Asynchronous event generator.
 • Create it.
 • Do other stuff while it’s working.
 • Pick up the next result later.
• Blocks or returns “incomplete” if not done.
 • Implementation decides which.
 • Future release may let the caller decide.
Timer Promise (1 of 2)

  use Reflex::Interval;

• my $one = Reflex::Interval->new(
•    interval => 1
• );
  my $two = Reflex::Interval->new(
     interval => 2
  );
Timer Promise (1 of 2)

  use Reflex::Interval;

  my $one = Reflex::Interval->new(
     interval => 1
  );

• my $two = Reflex::Interval->new(
•    interval => 2
• );
Timer Promise (2 of 2)

  print "Before   : ", time(), "n";

• my $event = $two->next();
• print "After two: ", time(), "n";
  $event = $one->next();
  print "After one: ", time(), "n";
Timer Promise (2 of 2)

  print "Before   : ", time(), "n";

  my $event = $two->next();
  print "After two: ", time(), "n";

• $event = $one->next();
• print "After one: ", time(), "n";
Eventy Timer Promise


    % perl promises.pl
•   Before   : 1295045065
                            Blocked 2 seconds.
•   After two: 1295045067
    After one: 1295045067
Eventy Timer Promise


    % perl promises.pl
    Before   : 1295045065
•   After two: 1295045067
                            Instant result.
•   After one: 1295045067
When to Avoid! Shun!

• Only use Reflex’s promises for
  asynchronous tasks that may need to wait.
• Synchronous generators and iterators are
  more efficient for computation.
“We were somewhere
around Asheville in the
   heart of the Blue
Ridge Mountains when
 the Moose began to
      take hold.”
Subclassing
Simpler Method
   Callbacks
Method Callbacks
    {
        package TickingThing;
        use Moose; extends "Reflex::Base";
        use Reflex::Interval;

•       has ticker => (
•         isa => "Reflex::Interval", is => "rw",
           default => sub {
              my $self = shift();
              Reflex::Interval->new(
                interval => 1, on_tick => [ $self, "callback" ],
              )
           },
        );

        sub callback { print "method got tick...n" }
    }

    Thing->new()->run_all();
Method Callbacks
    {
        package TickingThing;
        use Moose; extends "Reflex::Base";
        use Reflex::Interval;

        has ticker => (
           isa => "Reflex::Interval", is => "rw",
           default => sub {
              my $self = shift();
              Reflex::Interval->new(
•              interval => 1, on_tick => [ $self, "callback" ],
              )
           },
        );

•       sub callback { print "method got tick...n" }
    }

    Thing->new()->run_all();
Method Callbacks
   {
       package TickingThing;
       use Moose; extends "Reflex::Base";
       use Reflex::Interval;

       has ticker => (
          isa => "Reflex::Interval", is => "rw",
          default => sub {
             my $self = shift();
             Reflex::Interval->new(
               interval => 1, on_tick => [ $self, "callback" ],
             )
          },
       );

       sub callback { print "method got tick...n" }
   }

• Thing->new()->run_all();
Subclassed Interval
    {
•       package TickingThing;
        use Moose;
•       extends "Reflex::Interval";

        before on_tick => sub {
           print "customized tick...n"
        };
    }

    TickingThing->new( interval => 1 )->run_all();
Subclassed Interval
    {
        package TickingThing;
        use Moose;
        extends "Reflex::Interval";

•       before on_tick => sub {
•         print "customized tick...n"
        };
    }

    TickingThing->new( interval => 1 )->run_all();
Subclassed Interval
  {
      package TickingThing;
      use Moose;
      extends "Reflex::Interval";

      before on_tick => sub {
         print "customized tick...n"
      };
  }

• TickingThing->new( interval => 1 )->run_all();
Roles
Roles

• They’re sticky.
• They’re delicious.
• They’re high in carbohydrate calories.
• They may contain bacon.
Reflex Roles

• Eventy features are implemented as roles.
 • Consume them when appropriate.
• Each role has a corresponding class.
 • Reflex::Interval is Reflex::Role::Interval.
Reflex::Interval (1 of 3)
  package Reflex::Interval;
  use Moose; extends "Reflex::Base";

• has interval => (
       isa => "Num", is   => "rw"
  );

• has auto_repeat => (
       isa => "Bool", is => "ro", default => 1
  );

• has auto_start => (
       isa => "Bool", is => "ro", default => 1
  );
Reflex::Interval (2 of 3)
    with "Reflex::Role::Interval" => {
•      att_interval    => "interval",
•      att_auto_start => "auto_start",
•      att_auto_repeat => "auto_repeat",
       cb_tick         => "on_tick",
       method_start    => "start",
       method_stop     => "stop",
       method_repeat   => "repeat",
    };

    sub on_tick {
      my ($self, $args) = @_;
      $self->emit(
         event => "tick", args => $args
      );
    }
Reflex::Interval (2 of 3)
    with "Reflex::Role::Interval" => {
       att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
•      cb_tick         => "on_tick",
       method_start    => "start",
       method_stop     => "stop",
       method_repeat   => "repeat",
    };

•   sub on_tick {
      my ($self, $args) = @_;
•     $self->emit(
•        event => "tick", args => $args
      );
    }
Reflex::Interval (2 of 3)
    with "Reflex::Role::Interval" => {
       att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
       cb_tick         => "on_tick",
•      method_start    => "start",
•      method_stop     => "stop",
•      method_repeat   => "repeat",
    };

    sub on_tick {
      my ($self, $args) = @_;
      $self->emit(
         event => "tick", args => $args
      );
    }
Reflex::Interval (3 of 3)



      1;
Parameterized Roles

• Reflex uses role
  parameters to wire
  together code.

• MooseX::Role::
  Parameterized rocks
  for this.
Three Kinds of
Role Parameters
Attribute Parameters


• Name attributes in the consumer that
  control role behavior.
• Begin with “att_”.
Attribute Parameters
  package Reflex::Interval;
  use Moose;

• has interval => ( isa => "Num", ... );
• has auto_start => ( isa => "Bool", ... );
  ...;

  with "Reflex::Role::Interval" => {
     att_interval   => "interval",
     att_auto_start => "auto_start",
     ...,
  };
Attribute Parameters
    package Reflex::Interval;
    use Moose;

    has interval   => ( isa => "Num", ... );
    has auto_start => ( isa => "Bool", ... );
    ...;

    with "Reflex::Role::Interval" => {
•      att_interval   => "interval",
•      att_auto_start => "auto_start",
       ...,
    };
Callback Parameters

• Name consumer methods to call back
  when things happen.
• Begin with “cb_”.
• These callbacks are simple, synchronous
  method calls.
Callback Parameters
    package Reflex::Interval;
    use Moose;
    ...;

    with "Reflex::Role::Interval" => {
•      cb_tick => "on_tick",
       ...,
    };

• sub on_tick {
        my ($self, $args_hash) = @_;
        ...;
    }
Method Parameters

• Roles may implement public API methods.
• Classes get to decide what they’re called.
• Begin with “method_”.
Method Parameters
    {
        package Reflex::Interval;
        use Moose; extends "Reflex::Base";

        with "Reflex::Role::Interval" => {
           ...,
•         method_start => "start",
•         method_stop   => "stop",
        };
    }

    my $interval = Reflex::Interval->new();
•   $interval->stop();
•   $interval->start();
Lots of
   Role
Parameters
Awesome
   but
tedious to
configure.
Dynamic Defaults

• Each role designates a primary attribute
  parameter.
• Other parameter default values are based
  on the primary parameter’s value.
• Avoids namespace clashes as an extension
  of basic OO.
Primary Attribute
    with "Reflex::Role::Interval" => {
•     att_interval => "watchdog",
      ...,
    }


Role Parameter            Default Name

    method_start       start_watchdog()

    method_stop         stop_watchdog()

      cb_tick         on_watchdog_tick()
Primary Attribute
    with "Reflex::Role::Interval" => {
•     att_interval => "log_rotation",
      ...,
    }


Role Parameter            Default Name

    method_start     start_log_rotation()

    method_stop      stop_log_rotation()

      cb_tick       on_log_rotation_tick()
Primary Attribute
    with "Reflex::Role::Interval" => {
•      att_interval    => "interval",
•      att_auto_start => "auto_start",
•      att_auto_repeat => "auto_repeat",
•      cb_tick         => "on_tick",
•      method_start    => "start",
•      method_stop     => "stop",
•      method_repeat   => "repeat",
    };


           Redundancy is a special case.
       It overrides generally useful defaults.
Primary Attribute
    with "Reflex::Role::Interval" => {
•      att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
•      cb_tick         => "on_tick",
       method_start    => "start",
       method_stop     => "stop",
       method_repeat   => "repeat",
    };


Calls $self->on_tick()
         ... not $self->on_interval_tick()
Primary Attribute
    with "Reflex::Role::Interval" => {
•      att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
       cb_tick         => "on_tick",
•      method_start    => "start",
       method_stop     => "stop",
       method_repeat   => "repeat",
    };


Creates $interval->start()
       ... not $interval->start_interval()
Primary Attribute
    with "Reflex::Role::Interval" => {
•      att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
       cb_tick         => "on_tick",
       method_start    => "start",
•      method_stop     => "stop",
       method_repeat   => "repeat",
    };


Creates $interval->stop()
        ... not $interval->stop_interval()
Primary Attribute
    with "Reflex::Role::Interval" => {
•      att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
       cb_tick         => "on_tick",
       method_start    => "start",
       method_stop     => "stop",
•      method_repeat   => "repeat",
    };


                       Etc.
Other
Moose
Magic
Expose Inner
 Workings
Expose Inner Workings
    {
•       package AnotherTickingThing;
•       use Moose; extends "TickingThing";

        has "+ticker" => (
           handles => [ "interval" ],
        );
    }

    my $thing = AnotherTickingThing->new();
    $thing->interval(0.1);
    $thing->run_all();
Expose Inner Workings
    {
        package AnotherTickingThing;
        use Moose; extends "TickingThing";

•       has "+ticker" => (
•          handles => [ "interval" ],
•       );
    }

    my $thing = AnotherTickingThing->new();
    $thing->interval(0.1);
    $thing->run_all();
Expose Inner Workings
    {
        package AnotherTickingThing;
        use Moose; extends "TickingThing";

        has "+ticker" => (
           handles => [ "interval" ],
        );
    }

    my $thing = AnotherTickingThing->new();
•   $thing->interval(0.1);
    $thing->run_all();
Replace Inner
 Workings
Replace Inner Workings
  my $thing = TickingThing->new();

• $thing->ticker(
•   Reflex::Interval->new(
•     interval => 0.125,
           on_tick => [ $thing, "callback" ],
       )
  );

  $thing->run_all();
Replace Inner Workings

• my $thing = TickingThing->new(
         ticker => Reflex::Interval->new(
           interval => 0.125,
•          on_tick => [ $thing, "callback" ],
         )
    );



            Can’t use $thing like this.
    It must be declared before it can be used.
Replace Inner Workings
• my $thing;
• $thing = TickingThing->new(
         ticker => Reflex::Interval->new(
           interval => 0.125,
•          on_tick => [ $thing, "callback" ],
         )
    );



                Two statements.
    Reference to $thing held inside $thing.
Replace Inner Workings
• my $thing = TickingThing->new();
• $thing->ticker(
         Reflex::Interval->new(
           interval => 0.125,
•          on_tick => [ $thing, "callback" ],
         )
    );


          Dynamically replace it later.
    Reference to $thing held inside $thing.
Replace Inner Workings
    my $thing = TickingThing->new();

    $thing->ticker(
       Reflex::Interval->new(
         interval => 0.125,
•        on_tick => [ $thing, "callback" ],
       )
    );


    Either way, Reflex automatically weakens the
              inner reference for you.
Override
Attributes
Override Attributes
    {
•       package FasterInterval;
•       use Moose; extends "Reflex::Interval";

        has "+interval" => (
           default => 0.5,
        );
    }

    FasterInterval->new()->run_all();
Override Attributes
    {
        package FasterInterval;
        use Moose; extends "Reflex::Interval";

•       has "+interval" => (
•         default => 0.5,
        );
    }

    FasterInterval->new()->run_all();
Override Attributes
  {
      package FasterInterval;
      use Moose; extends "Reflex::Interval";

      has "+interval" => (
         default => 0.5,
      );
  }

• FasterInterval->new()->run_all();
Whatever
Objects
Can Do
What Can’t
Objects Do?
    ☺
Reflex
How does it work?
   Rocco Caputo – @rcaputo
          YAPC::NA
     Tuesday, 28 June 2011
        Around Teatime
Static Reflex
      =
   Moose
Dynamic
 Reflex
   =
 Emit &
 Watch
Crossing the
Barrier Between
Static & Dynamic
   Interaction
Static to Dynamic
• Classes are built using static roles.
• Classes implement additional features.
• Callbacks within a class are synchronous.
• Classes emit dynamic messages.
• Dynamic object interaction is based on
  watching for those messages.
Default Callback
    with "Reflex::Role::Interval" => {
       att_interval    => "interval",
       att_auto_start => "auto_start",
       att_auto_repeat => "auto_repeat",
•      cb_tick         => "on_tick",
       method_start    => "start",
       method_stop     => "stop",
       method_repeat   => "repeat",
    };

•   sub on_tick {
      my ($self, $args) = @_;
•     $self->emit(
•        event => "tick", args => $args
      );
    }
Dynamic back to Static?


  Just Call
Stuff, Okay?
Trade Offs

• Dynamic object interaction is richer, more
  fun, and often necessary.
• Beware of using dynamic messages solely
  “for fun’s sake”.
• Static callbacks are more efficient.
Emitting an Event
•   package Moosian; use Moose;
•   extends "Reflex::Base";

    has name => ( is => "ro", isa => "Str" );

    sub yip {
      my ($self, $args) = @_;
      print(
         $self->name(),
         " says: Yip-yip-yip-yip..",
         " uh-huh uh-huh..n"
      );
      $self->emit( event => "yipped" );
    }

    1;
Emitting an Event
    package Moosian; use Moose;
    extends "Reflex::Base";

    has name => ( is => "ro", isa => "Str" );

•   sub yip {
      my ($self, $args) = @_;
•     print(
•        $self->name(),
•        " says: Yip-yip-yip-yip..",
•        " uh-huh uh-huh..n"
•     );
      $self->emit( event => "yipped" );
    }

    1;
Emitting an Event
    package Moosian; use Moose;
    extends "Reflex::Base";

    has name => ( is => "ro", isa => "Str" );

    sub yip {
      my ($self, $args) = @_;
      print(
         $self->name(),
         " says: Yip-yip-yip-yip..",
         " uh-huh uh-huh..n"
      );
•     $self->emit( event => "yipped" );
    }

    1;
Emitting Events

• Objects emit() events as part of their
  public interfaces.
• Events have no explicit destination.
• It’s up to users to watch() for events.
Watching Events

• my $bob = Moosian->new( name => "Bob" );
  my $joe = Moosian->new( name => "Joe" );

• $bob->watch( $joe, "yipped", "yip" );
  $joe->watch( $bob, "yipped", "yip" );

  $bob->yip();

  Reflex->run_all();
Watching Events

    my $bob = Moosian->new( name => "Bob" );
•   my $joe = Moosian->new( name => "Joe" );

    $bob->watch( $joe, "yipped", "yip" );
•   $joe->watch( $bob, "yipped", "yip" );

    $bob->yip();

    Reflex->run_all();
Watching Events

  my $bob = Moosian->new( name => "Bob" );
  my $joe = Moosian->new( name => "Joe" );

  $bob->watch( $joe, "yipped", "yip" );
  $joe->watch( $bob, "yipped", "yip" );

• $bob->yip();
• Reflex->run_all();
Moosian Dialog
Bob   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Joe   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Bob   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Joe   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Bob   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Joe   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Bob   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Joe   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Bob   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
Joe   says:   Yip-yip-yip-yip...   uh-huh   uh-huh..
^C
Infinite Recursion OK
        TIME     RSS COMMAND
•    1:16.60   17940 perl moosians.pl

        TIME     RSS COMMAND
     2:37.94   17940 perl moosians.pl

        TIME     RSS COMMAND
     3:05.86   17940 perl moosians.pl

        TIME     RSS COMMAND
     3:30.69   17940 perl moosians.pl
Infinite Recursion OK
        TIME     RSS COMMAND
     1:16.60   17940 perl moosians.pl

        TIME     RSS COMMAND
•    2:37.94   17940 perl moosians.pl

        TIME     RSS COMMAND
     3:05.86   17940 perl moosians.pl

        TIME     RSS COMMAND
     3:30.69   17940 perl moosians.pl
Infinite Recursion OK
        TIME     RSS COMMAND
     1:16.60   17940 perl moosians.pl

        TIME     RSS COMMAND
     2:37.94   17940 perl moosians.pl

        TIME     RSS COMMAND
•    3:05.86   17940 perl moosians.pl

        TIME     RSS COMMAND
     3:30.69   17940 perl moosians.pl
Infinite Recursion OK
        TIME     RSS COMMAND
     1:16.60   17940 perl moosians.pl

        TIME     RSS COMMAND
     2:37.94   17940 perl moosians.pl

        TIME     RSS COMMAND
     3:05.86   17940 perl moosians.pl

        TIME     RSS COMMAND
•    3:30.69   17940 perl moosians.pl
Simplified
Hierarchical
 Watching
Hierarchical Watching?
• Most program
  structure is
  hierarchical.

• Trees of objects
  that use other
  objects.

• Parent objects
  often need results
  from children.
Moose Traits
  Rock
Watched
Attributes
Callbacks
Discovered by
    Name
Watched Attributes
• use Reflex::Trait::Watched qw(watches);
• watches clock => (
       isa    => "Reflex::Interval",
       setup => sub {
          Reflex::Interval->new(interval => 1)
       },
  );

  sub on_clock_tick { print "tick...n" }
Watched Attributes
  use Reflex::Trait::Watched qw(watches);

  watches clock => (
     isa    => "Reflex::Interval",
     setup => sub {
        Reflex::Interval->new(interval => 1)
     },
  );

• sub on_clock_tick { print "tick...n" }
Watched Attributes
  use Reflex::Trait::Watched qw(watches);

  watches clock => (
     isa    => "Reflex::Interval",
     setup => sub {
        Reflex::Interval->new(interval => 1)
     },
  );

• sub on_clock_tick { print "tick...n" }
Watched Attributes
  use Reflex::Trait::Watched qw(watches);

• watches clock => (
       isa    => "Reflex::Interval",
       setup => sub {
          Reflex::Interval->new(interval => 1)
       },
  );

• sub on_clock_tick { print "tick...n" }
Watched Attributes
    use Reflex::Trait::Watched qw(watches);

    watches clock => (
•      isa    => "Reflex::Interval",
       setup => sub {
          Reflex::Interval->new(interval => 1)
       },
    );

• sub on_clock_tick { print "tick...n" }
Watched Attributes
  use Reflex::Trait::Watched qw(watches);

• watches penguin => (
•   isa   => "Reflex::Bomb",
       setup => sub { ... },
  );

  sub on_penguin_tick { ... }
  sub on_penguin_stop { ... }
  sub on_penguin_explode { ... }
Watched Attributes
  use Reflex::Trait::Watched qw(watches);

  watches penguin => (
     isa   => "Reflex::Bomb",
     setup => sub { ... },
  );

• sub on_penguin_tick { ... }
• sub on_penguin_stop { ... }
• sub on_penguin_explode { ... }
Watched Attributes

  use Reflex::Trait::Watched qw(watches);

• watches watchdog => ( ... Interval ... );
• watches log_mark => ( ... Interval ... );
• sub on_watchdog_tick { ... }
• sub on_log_mark_tick { ... }
Reflex Role
Composition
Two-Way Pipe Driver


• Bidirectionally stream data between two
  file handles.
• Useful for proxies.
Two File Handles
•   package Proxy;

    use Moose;
    extends "Reflex::Base";

•   has client => (
•     isa => "FileHandle",
      is => "rw", required => 1 );

•   has server => (
•     isa => "FileHandle",
      is => "rw", required => 1 );

•   has active => (
•     isa => "Bool",
      is => "ro", default => 1 );
Reduced for Example

• use Reflex::Callbacks "make_null_handler";
• make_null_handler("on_client_closed");
• make_null_handler("on_client_error");
• make_null_handler("on_server_closed");
• make_null_handler("on_server_error");
From Client to Server

• with "Reflex::Role::Streaming" => {
         att_active => "active",
•        att_handle => "client",
    };

    sub on_client_data {
      my ($self, $arg) = @_;
      $self->put_server($arg->{data});
    }
From Client to Server

    with "Reflex::Role::Streaming" => {
       att_active => "active",
       att_handle => "client",
    };

• sub on_client_data {
        my ($self, $arg) = @_;
•       $self->put_server($arg->{data});
    }
From Server to Client

• with "Reflex::Role::Streaming" => {
         att_active => "active",
•        att_handle => "server",
    };

    sub on_server_data {
      my ($self, $arg) = @_;
      $self->put_client($arg->{data});
    }
From Server to Client

    with "Reflex::Role::Streaming" => {
       att_active => "active",
       att_handle => "server",
    };

• sub on_server_data {
        my ($self, $arg) = @_;
•       $self->put_client($arg->{data});
    }
We’re “Done”



  1;
Quote-Done-Unquote
• Not handling EOF (cb_closed).
• Not handling errors (cb_error).
• We’ll probably need separate “active” flags
  for client and server later.
• Flow-control for data rate mismatches?
• Etc.
Usage

  # Assume we already have the sockets.

• my $p = Proxy->new(
•   client => $client_socket,
•   server => $server_socket,
  );

  # Do something else while it runs.
Simple?
I Wrote What?
                         Reflex::Role::Writable
                         att_handle                                 Reflex::Role::Reading
                         att_active                                 att_handle
                         cb_ready                                   cb_closed
                         method_pause                               cb_data
                         method_resume                              cb_error
                         method_start                               method_read              Reflex::Role::Readable
Reflex::Role::Writing     method_stop                                                         att_handle
att_handle                                                                                   att_active
cb_error                                                                                     cb_ready
method_put                                                                                   method_pause
method_flush                                              Proxy                               method_resume
                                                 client                                      method_stop
                                                 server
                        Reflex::Role::Streaming   active             Reflex::Role::Streaming
                        att_handle               on_client_data     att_handle
                        att_active               on_client_closed   att_active
                        cb_data                  on_client_error    cb_data
                        cb_closed                put_client         cb_closed
                        cb_error                 stop_client        cb_error
                        method_put               on_server_data     method_put
                        method_stop              on_server_closed   method_stop
                                                 on_server_error
Reflex::Role::Readable                            put_server
att_handle                                       stop_server                                 Reflex::Role::Writing
att_active                                                                                   att_handle
cb_ready                                                                                     cb_error
method_pause                                                                                 method_put
                                                                    Reflex::Role::Writable
method_resume                                                                                method_flush
                          Reflex::Role::Reading                      att_handle
method_stop
                          att_handle                                att_active
                          cb_closed                                 cb_ready
                          cb_data                                   method_pause
                          cb_error                                  method_resume
                          method_read                               method_start
                                                                    method_stop
Reflex::Role::Streaming
Reflex
                       The ability to....
 Role
Reading     ... read data from a non-blocking file handle.

Readable     ... watch for data arriving on a file handle.

Writing    ... buffer and/or write data to a NB file handle.

Writable   ... watch a file handle for ability to write data.
Relax–It’s Just the Class


• That’s the Proxy class.
• All instances will share the same code.
Overkill? Dial it Back!

   Roles let
programs pick
and mix what
  they need.
Reflex::Role::InStreaming
            Reflex::Role::InStreaming
            att_handle
            att_active
            cb_data
            cb_closed
            cb_error
            method_stop



  Reflex::Role::Readable   Reflex::Role::Reading
  att_handle              att_handle
  att_active              cb_closed
  cb_ready                cb_data
  method_pause            cb_error
  method_resume           method_read
  method_stop
Reflex::Role::OutStreaming
             Reflex::Role::OutStreaming
             att_handle
             att_active
             cb_data
             cb_closed
             cb_error
             method_put
             method_stop



    Reflex::Role::Writable
    att_handle
                            Reflex::Role::Writing
    att_active
                            att_handle
    cb_ready
                            cb_error
    method_pause
                            method_put
    method_resume
                            method_flush
    method_start
    method_stop
Dynamic
  Fun
SmallTalk-Like
 Messaging
Auto-Emit
Messages When
  Attributes
   Change
SmallTalk Messaging
• package EmittingCounter;
• use Reflex::Trait::EmitsOnChange qw(emits);
  emits count => (
     isa => "Int", default => 0
  );

  sub something_happens {
    my $self = shift;
    $self->count($self->count() + 1);
  }
SmallTalk Messaging
    package EmittingCounter;

    use Reflex::Trait::EmitsOnChange qw(emits);

• emits count => (
         isa => "Int", default => 0
    );

    sub something_happens {
      my $self = shift;
•     $self->count($self->count() + 1);
    }
Now Watch It
• use EmittingCounter;
  use Reflex::Trait::Watched qw(watches);

• watches counter => (
•   isa   => "EmittingCounter",
       setup => sub { EmittingCounter-> new() },
  );

  sub on_counter_count {
    my ($self, $args) = @_;
    print "counter reached $args->{value}n";
  }
Now Watch It
    use EmittingCounter;
    use Reflex::Trait::Watched qw(watches);

    watches counter => (
       isa   => "EmittingCounter",
       setup => sub { EmittingCounter-> new() },
    );

• sub on_counter_count {
        my ($self, $args) = @_;
•       print "counter reached $args->{value}n";
    }
Self-
 Managed
Collections
Reflex::Collection

• Manages objects that do
  Reflex::Role::Collectible.
• Collectible objects are automatically
  cleaned up when they stop.
• Great for create-and-forget things.
Echo Server (1 of 1)
    {
•       package TcpEchoServer; use Moose;
•       extends "Reflex::Acceptor"; use EchoStream;
        use Reflex::Collection qw(has_many);

        has_many clients => (
           handles => {
             remember_client => "remember"
           }
        );

        sub on_accept {
          my ($self, $args) = @_;
          $self->remember_client(
             EchoStream->new( handle => $args->{socket} )
          );
        }
    }
Echo Server (1 of 1)
    {
        package TcpEchoServer; use Moose;
•       extends "Reflex::Acceptor"; use EchoStream;
        use Reflex::Collection qw(has_many);

        has_many clients => (
           handles => {
             remember_client => "remember"
           }
        );

        sub on_accept {
          my ($self, $args) = @_;
          $self->remember_client(
             EchoStream->new( handle => $args->{socket} )
          );
        }
    }
Echo Server (1 of 1)
    {
        package TcpEchoServer; use Moose;
        extends "Reflex::Acceptor"; use EchoStream;
•       use Reflex::Collection qw(has_many);

        has_many clients => (
           handles => {
             remember_client => "remember"
           }
        );

        sub on_accept {
          my ($self, $args) = @_;
          $self->remember_client(
             EchoStream->new( handle => $args->{socket} )
          );
        }
    }
Echo Server (1 of 1)
    {
        package TcpEchoServer; use Moose;
        extends "Reflex::Acceptor"; use EchoStream;
        use Reflex::Collection qw(has_many);

•       has_many clients => (
•         handles => {
•            remember_client => "remember"
           }
        );

        sub on_accept {
          my ($self, $args) = @_;
          $self->remember_client(
             EchoStream->new( handle => $args->{socket} )
          );
        }
    }
Echo Server (1 of 1)
    {
        package TcpEchoServer; use Moose;
        extends "Reflex::Acceptor"; use EchoStream;
        use Reflex::Collection qw(has_many);

        has_many clients => (
           handles => {
             remember_client => "remember"
           }
        );

•       sub on_accept {
          my ($self, $args) = @_;
•         $self->remember_client(
•           EchoStream->new( handle => $args->{socket} )
          );
        }
    }
EchoStream (1 of 1)
• package EchoStream;
    use Moose;
•   extends "Reflex::Stream";

    sub on_data {
      my ($self, $args) = @_;
      $self->put($args->{data});
    }

    1;
EchoStream (1 of 1)
    package EchoStream;
    use Moose;
    extends "Reflex::Stream";

• sub on_data {
         my ($self, $args) = @_;
•        $self->put($args->{data});
    }

    1;
POE
Compatibility
Benefits of POE
• Mature and stable.
• Use any event loop you want.
• Hundreds of existing modules.
• Thousands of users.
• And you.
 • Don’t rewrite everything at once.
POE Compatibility
• Migrate incrementally.
 • Reflex can talk to POE modules.
 • POE modules can talk to Reflex objects.
 • “Separate but equal” is not enough.
• Static Reflex is faster than POE message
  passing.
• Reflex eg directory contains examples.
“But is Reflex
   Ready?”
40% Complete!
• Large swathes of design are stable.
• Documentation!
 • ... which I broke preparing for this talk.
• Bugs!
 • ... which I added preparing for this talk.
• Roadmap documented in the repository.
Help Make It Better
• http://github.com/rcaputo/reflex
 • See the roadmap.
• #reflex on irc.perl.org
• poe-subscribe@perl.org
• Hackathon, BOF or hallway track.
• Use it, and complain... to me.
• Influence the project while it’s still plastic.
Contribute to a Project
• Nick Perez’s Reflex-based psgi server.
• Reflexive::Role::Collective
       Interact with a collection of reflexive objects.
• Reflexive::Role::DataMover
                   Move data between two streams.
• Reflexive::Role::TCPServer
                Become a fully featured TCP server.
• Reflexive::Stream::Filtering
                Apply POE filters to Reflex streams.
• (Your Project Here)
Thank you!
Webliography
Drawing of Edgar Allan    Self-Herding Cat
Poe.
                          ORM Diagram
“A Softer World” comic.
                          POE's users are
Wizard Moose              outstanding in their fields.
Edgar Allan Bro           Moose Antlers
Universum                 Promise Ring
Tiled Angry Moose         The Watchers
Accidental Goatse         A Fighter Jet Made of
(Unused)                  Biceps

Contenu connexe

Tendances

How Secure Are Docker Containers?
How Secure Are Docker Containers?How Secure Are Docker Containers?
How Secure Are Docker Containers?Ben Hall
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScriptMosky Liu
 
Rust: Reach Further
Rust: Reach FurtherRust: Reach Further
Rust: Reach Furthernikomatsakis
 
The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202Mahmoud Samir Fayed
 
Debugging Complex Systems - Erlang Factory SF 2015
Debugging Complex Systems - Erlang Factory SF 2015Debugging Complex Systems - Erlang Factory SF 2015
Debugging Complex Systems - Erlang Factory SF 2015lpgauth
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011Charles Nutter
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLabIntroduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLabCloudxLab
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbikailan
 
The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210Mahmoud Samir Fayed
 
Do you Promise?
Do you Promise?Do you Promise?
Do you Promise?jungkees
 
Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011Puppet
 
The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...
The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...
The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...Andrew Kozma
 
Beyond the Callback: Yield Control with Javascript Generators
Beyond the Callback: Yield Control with Javascript GeneratorsBeyond the Callback: Yield Control with Javascript Generators
Beyond the Callback: Yield Control with Javascript GeneratorsDarren Cruse
 
Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Metosin Oy
 
Puppet Module Reusability - What I Learned from Shipping to the Forge
Puppet Module Reusability - What I Learned from Shipping to the ForgePuppet Module Reusability - What I Learned from Shipping to the Forge
Puppet Module Reusability - What I Learned from Shipping to the ForgePuppet
 
A Modest Introduction To Swift
A Modest Introduction To SwiftA Modest Introduction To Swift
A Modest Introduction To SwiftJohn Anderson
 

Tendances (20)

How Secure Are Docker Containers?
How Secure Are Docker Containers?How Secure Are Docker Containers?
How Secure Are Docker Containers?
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScript
 
Rust: Reach Further
Rust: Reach FurtherRust: Reach Further
Rust: Reach Further
 
The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202
 
Debugging Complex Systems - Erlang Factory SF 2015
Debugging Complex Systems - Erlang Factory SF 2015Debugging Complex Systems - Erlang Factory SF 2015
Debugging Complex Systems - Erlang Factory SF 2015
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLabIntroduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
Introduction to Apache ZooKeeper | Big Data Hadoop Spark Tutorial | CloudxLab
 
Decorators demystified
Decorators demystifiedDecorators demystified
Decorators demystified
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodb
 
The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210
 
Do you Promise?
Do you Promise?Do you Promise?
Do you Promise?
 
Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011Oliver hookins puppetcamp2011
Oliver hookins puppetcamp2011
 
ElasticSearch
ElasticSearchElasticSearch
ElasticSearch
 
Introduce Django
Introduce DjangoIntroduce Django
Introduce Django
 
The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...
The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...
The best defense is a good offense (April 2013 Presentation to Atlantic HTCIA...
 
Beyond the Callback: Yield Control with Javascript Generators
Beyond the Callback: Yield Control with Javascript GeneratorsBeyond the Callback: Yield Control with Javascript Generators
Beyond the Callback: Yield Control with Javascript Generators
 
Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Clojure in real life 17.10.2014
Clojure in real life 17.10.2014
 
Puppet Module Reusability - What I Learned from Shipping to the Forge
Puppet Module Reusability - What I Learned from Shipping to the ForgePuppet Module Reusability - What I Learned from Shipping to the Forge
Puppet Module Reusability - What I Learned from Shipping to the Forge
 
A Modest Introduction To Swift
A Modest Introduction To SwiftA Modest Introduction To Swift
A Modest Introduction To Swift
 

En vedette

H reflex (Hoffmann's Reflex)
H reflex (Hoffmann's Reflex)H reflex (Hoffmann's Reflex)
H reflex (Hoffmann's Reflex)Murtaza Syed
 
Micturation reflex by Dr Irum
Micturation reflex by Dr Irum Micturation reflex by Dr Irum
Micturation reflex by Dr Irum SMS_2015
 
Anatomy of spinal cord
Anatomy of spinal cordAnatomy of spinal cord
Anatomy of spinal cordMBBS IMS MSU
 

En vedette (6)

H reflex (Hoffmann's Reflex)
H reflex (Hoffmann's Reflex)H reflex (Hoffmann's Reflex)
H reflex (Hoffmann's Reflex)
 
Cardiac reflex
Cardiac reflexCardiac reflex
Cardiac reflex
 
Reflexes
Reflexes Reflexes
Reflexes
 
Micturation reflex by Dr Irum
Micturation reflex by Dr Irum Micturation reflex by Dr Irum
Micturation reflex by Dr Irum
 
Micturition reflex
Micturition reflexMicturition reflex
Micturition reflex
 
Anatomy of spinal cord
Anatomy of spinal cordAnatomy of spinal cord
Anatomy of spinal cord
 

Similaire à Reflex - How Does It Work? (extended dance remix)

Reflex - How does it work?
Reflex - How does it work?Reflex - How does it work?
Reflex - How does it work?Rocco Caputo
 
PyCon Philippines 2012 Keynote
PyCon Philippines 2012 KeynotePyCon Philippines 2012 Keynote
PyCon Philippines 2012 KeynoteDaniel Greenfeld
 
Boost Maintainability
Boost MaintainabilityBoost Maintainability
Boost MaintainabilityMosky Liu
 
Test First Teaching
Test First TeachingTest First Teaching
Test First TeachingSarah Allen
 
Memory Management In Python The Basics
Memory Management In Python The BasicsMemory Management In Python The Basics
Memory Management In Python The BasicsNina Zakharenko
 
The hangover: A "modern" (?) high performance approach to build an offensive ...
The hangover: A "modern" (?) high performance approach to build an offensive ...The hangover: A "modern" (?) high performance approach to build an offensive ...
The hangover: A "modern" (?) high performance approach to build an offensive ...Nelson Brito
 
Test First Teaching and the path to TDD
Test First Teaching and the path to TDDTest First Teaching and the path to TDD
Test First Teaching and the path to TDDSarah Allen
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxAndrzej Sitek
 
Rubinius - A Tool of the Future
Rubinius - A Tool of the FutureRubinius - A Tool of the Future
Rubinius - A Tool of the Futureevanphx
 
How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.jsPiotr Pelczar
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)tarcieri
 
Charles nutter star techconf 2011 - jvm languages
Charles nutter   star techconf 2011 - jvm languagesCharles nutter   star techconf 2011 - jvm languages
Charles nutter star techconf 2011 - jvm languagesStarTech Conference
 
Lecture. Advanced Reflection: MetaLinks
Lecture. Advanced Reflection: MetaLinksLecture. Advanced Reflection: MetaLinks
Lecture. Advanced Reflection: MetaLinksMarcus Denker
 
Asynchronous Awesome
Asynchronous AwesomeAsynchronous Awesome
Asynchronous AwesomeFlip Sasser
 
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinksVUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinksMarcus Denker
 
Playing Go with Clojure
Playing Go with ClojurePlaying Go with Clojure
Playing Go with Clojureztellman
 
Esoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in RubyEsoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in Rubymametter
 
Lecture: Advanced Reflection. MetaLinks
Lecture: Advanced Reflection. MetaLinksLecture: Advanced Reflection. MetaLinks
Lecture: Advanced Reflection. MetaLinksMarcus Denker
 
Py4inf 05-iterations (1)
Py4inf 05-iterations (1)Py4inf 05-iterations (1)
Py4inf 05-iterations (1)karan saini
 

Similaire à Reflex - How Does It Work? (extended dance remix) (20)

Reflex - How does it work?
Reflex - How does it work?Reflex - How does it work?
Reflex - How does it work?
 
PyCon Philippines 2012 Keynote
PyCon Philippines 2012 KeynotePyCon Philippines 2012 Keynote
PyCon Philippines 2012 Keynote
 
Boost Maintainability
Boost MaintainabilityBoost Maintainability
Boost Maintainability
 
Test First Teaching
Test First TeachingTest First Teaching
Test First Teaching
 
Memory Management In Python The Basics
Memory Management In Python The BasicsMemory Management In Python The Basics
Memory Management In Python The Basics
 
The hangover: A "modern" (?) high performance approach to build an offensive ...
The hangover: A "modern" (?) high performance approach to build an offensive ...The hangover: A "modern" (?) high performance approach to build an offensive ...
The hangover: A "modern" (?) high performance approach to build an offensive ...
 
Ruby basics
Ruby basicsRuby basics
Ruby basics
 
Test First Teaching and the path to TDD
Test First Teaching and the path to TDDTest First Teaching and the path to TDD
Test First Teaching and the path to TDD
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
 
Rubinius - A Tool of the Future
Rubinius - A Tool of the FutureRubinius - A Tool of the Future
Rubinius - A Tool of the Future
 
How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.js
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)
 
Charles nutter star techconf 2011 - jvm languages
Charles nutter   star techconf 2011 - jvm languagesCharles nutter   star techconf 2011 - jvm languages
Charles nutter star techconf 2011 - jvm languages
 
Lecture. Advanced Reflection: MetaLinks
Lecture. Advanced Reflection: MetaLinksLecture. Advanced Reflection: MetaLinks
Lecture. Advanced Reflection: MetaLinks
 
Asynchronous Awesome
Asynchronous AwesomeAsynchronous Awesome
Asynchronous Awesome
 
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinksVUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
VUB Brussels Lecture 2019: Advanced Reflection: MetaLinks
 
Playing Go with Clojure
Playing Go with ClojurePlaying Go with Clojure
Playing Go with Clojure
 
Esoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in RubyEsoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in Ruby
 
Lecture: Advanced Reflection. MetaLinks
Lecture: Advanced Reflection. MetaLinksLecture: Advanced Reflection. MetaLinks
Lecture: Advanced Reflection. MetaLinks
 
Py4inf 05-iterations (1)
Py4inf 05-iterations (1)Py4inf 05-iterations (1)
Py4inf 05-iterations (1)
 

Dernier

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
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
 
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
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Dernier (20)

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
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
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

Reflex - How Does It Work? (extended dance remix)

  • 1. Reflex How does it work? Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime
  • 4. Who Does He Think He Is? • Rocco Caputo or “rcaputo” most places. • http://search.cpan.org/~rcaputo/ • https://github.com/rcaputo • http://twitter.com/rcaputo
  • 10. The Other Committers • Adam Kennedy • Jonathan Steinert • Benjamin Smith • Larwan Berke • Casey West • Martijn van Beers • Chris Fedde • Matt Cashner • Chris Williams • Matt Sickler • David Davis • Perl Whore • David Webb • Philip Gwyn • Hinrik Örn Sigurðsson • Tom Feist • jmadler • Yuval Kogman
  • 11. The CPAN Authors Alejandro Imass • Alessandro Ranellucci • Anatoly Sharifulin • Andrew A. Chen • Andrew Hoying • Andrew Sterling Hanenkamp • Andrew V. Purshottam • Andy Grundman • Artur Bergman • Benjamin Trott • Brendan Beveridge • Chris Cobb • Chris Prather • Christian-Rolf Gruen • Curtis Hawthorne • Daisuke Maki • Daisuke Murase • Damien Krotkine • Dan McCormick • David Golden • David Snopek • Denis Pokataev • Dmitry Karasik • dmitry kim • Eriam Schaffter • Eric Waters • Erick Calder • George Nistorica • Greg Fast • Guillermo Roditi • Hans Dieter Pearcey • Ivan B. Serezhkin • J. J. Merelo Guervos • Jan Henning Thorsen • Jason McManus • Jeff Bisbee • Jeff Goff • Jerome Quelin • Johannes Plunien • Jonathan Ringstad • Jozef Kutej • Justin Hunter • Kazuhiro Osawa • Kevin L. Esteb • Kirill Miazine • Larry Shatzer Jr • Loic TROCHET • Marc Lehmann • Marc Mims • Mark A. Hershberger • Mark McConnell • Mark Morgan • Markus Mueller • Matthew O’Connor • Michael Ching • Michael R. Davis • Michael Schilli • Mike Fletcher • Mike Schroeder • Mischa Spiegelmock • MOCK • MSERGEANT • Nicholas Perez • Olivier ‘dolmen’ Mengue • Paul David Tinsley • Paul Driver • Paul Evans • Paul G Webster • Paul Visscher • Pavel Boldin • Pedro Melo • Peter Guzis • Przemyslaw Iskra • Rafael Kitover • Richard Clamp • Rob Bloodgood • Rob Partington • Robert ‘phaylon’ Sedlacek • Sawyer X • Scott Beck • Scott McCoy • Sean Egan • Sebastien Aperghis- Tramoni • Sergey Kotenko • Sergey Skvortsov • Sjors Gielen • Stephen Adkins • Steve James • Steve McNabb • Takeshi Miki • Tatsuhiko Miyagawa • Thiago Berlitz Rondon • Tony Cook • Torsten Raudssus • wb@95700.net • William Travis Holton • Yuji Suzuki • Yves Blusseau • Zoffix Znet
  • 15. Reflex What Is It? Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime
  • 16. Reflex What Isn’t It? Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime
  • 17. What can’t you do with a drunken sailor?
  • 18. Reflex is an only child waiting in the park.
  • 19. ⃠ Reflex is an only child waiting in the park.
  • 20. Reflex isn’t an event loop.
  • 21. CPAN already has too many event loops.
  • 22. Event loops are the means, not the ends.
  • 24. Nor is Reflex an object system.
  • 25. CPAN already has too many object systems.
  • 26. Reflex uses Moose
  • 27. But Why?! “I am disappointed that after all this time we have no consensus on how to say in Perl ‘Class X has attribute Y’ when so many other languages have solutions that have freed their users’ minds up to move on to higher-level problems.” — Peter Scott, on the Perl 5 Porters Mailing List
  • 28. But Why?! • Moose lets me solve higher-level problems. • Moose has sufficient adoption to survive. • The Meta-Object Protocol is insanely useful. • Moose will get better as native Perl OO improves.
  • 29. Reflex What Is It? Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime
  • 30. The ORM of Event Loops!!
  • 34. Plus a Reactor provided by Your Favorite Event Loop
  • 36. Like ORMs hide SQL ORM behind objects... DB
  • 37. Reflex hides event loops Reflex behind The Events objects... Can
  • 39. Reflex is Modern POE • POE = Perl Object Environment • Modern Perl objects are very different than 1998 Perl objects. • POE has a lot of users. • Start over with Reflex so POE remains compatible.
  • 40. Reflex unifies eventy interaction.
  • 41. Rule 34 for Perl If you can think of it, CPAN has a module for it.
  • 42. TIMTOWTDI If you can think of it, CPAN has 2+ incompatible modules for it...
  • 43. TIMTOWTDI ... and someday you’ll need to use both at once.
  • 44. TIMTOWTDI • There’s more than one way to pass events around. • The “best” way... depends. • Choosing poorly limits later options. • Reflex supports any or all at once.
  • 45. 3 ½ Rules Make it Work
  • 46. ⁓1⁓ Objects must not dictate callback mechanisms.
  • 47. ⁓ 1.5 ⁓ Users define how they receive callbacks.
  • 48. ⁓2⁓ The base system must support all desired callback types.
  • 49. ⁓3⁓ Reflex must do just enough work to be correct.
  • 52. Static Composition • Code is bolted together before running. • Subclassing. • Role composition. • All pieces built and destroyed together. • Most eventy abstractions ignore this.
  • 53. Dynamic Composition • Event watchers are created, • related (has-a), • communicated (with), • and destructicated • at run time. • Lather, rinse, repeat until the owner ends.
  • 54. Dynamic Lifetimes • Object provides service to one owner. • Object life is briefer than its owner. • Object’s lifespan matches its owner. • Good candidate for static composition. • Object provides service to 2+ subscribers. • Good candidate for breadboarding or publish/subscribe.
  • 55. Reflex Embraces, Extends and Consumes Both
  • 56. Examples are next.
  • 57. Reflex How to Use It! Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime
  • 59. Ye Olde Coderef use Reflex::Interval; • my $i_one = Reflex::Interval->new( • interval => 1, on_tick => sub { print "tick one...n" }, ); my $i_two = Reflex::Interval->new( interval => 0.5, on_tick => sub { print "tick two...n" }, ); Reflex->run_all();
  • 60. Ye Olde Coderef use Reflex::Interval; my $i_one = Reflex::Interval->new( interval => 1, • on_tick => sub { print "tick one...n" }, ); my $i_two = Reflex::Interval->new( interval => 0.5, on_tick => sub { print "tick two...n" }, ); Reflex->run_all();
  • 61. Ye Olde Coderef use Reflex::Interval; my $i_one = Reflex::Interval->new( interval => 1, on_tick => sub { print "tick one...n" }, ); • my $i_two = Reflex::Interval->new( • interval => 0.5, on_tick => sub { print "tick two...n" }, ); Reflex->run_all();
  • 62. Ye Olde Coderef use Reflex::Interval; my $i_one = Reflex::Interval->new( interval => 1, on_tick => sub { print "tick one...n" }, ); my $i_two = Reflex::Interval->new( interval => 0.5, • on_tick => sub { print "TICK TWO!!!n" }, ); Reflex->run_all();
  • 63. Ye Olde Coderef tick one... TICK TWO!!! TICK TWO!!! tick one... TICK TWO!!! TICK TWO!!! tick one... TICK TWO!!! TICK TWO!!! ^C
  • 64. Ye Olde Coderef - The Good • Quick and dead simple to use. • Convenient and fast for small things. • Parsimonious use of memory.
  • 65. Ye Olde Coderef - The Bad • Circular references and memory leaks— unless you explicitly manage memory. • Anti-pattern if done solely for speed... • Implementation detail wags the dog. • Giving up OO benefits for speed.
  • 66. Ye Olde Coderef - The Ugly # A twisty maze of coderefs, all alike. Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub { Watcher( sub {
  • 68. Method Callbacks { • package TickingThing; • use Moose; extends "Reflex::Base"; use Reflex::Interval; has ticker => ( isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( interval => 1, on_tick => [ $self, "callback" ], ) }, ); sub callback { print "method got tick...n" } } Thing->new()->run_all();
  • 69. Method Callbacks { package TickingThing; use Moose; extends "Reflex::Base"; use Reflex::Interval; • has ticker => ( • isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( interval => 1, on_tick => [ $self, "callback" ], ) }, ); sub callback { print "method got tick...n" } } Thing->new()->run_all();
  • 70. Method Callbacks { package TickingThing; use Moose; extends "Reflex::Base"; use Reflex::Interval; has ticker => ( isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( • interval => 1, on_tick => [ $self, "callback" ], ) }, ); sub callback { print "method got tick...n" } } Thing->new()->run_all();
  • 71. Method Callbacks { package TickingThing; use Moose; extends "Reflex::Base"; use Reflex::Interval; has ticker => ( isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( • interval => 1, on_tick => [ $self, "callback" ], ) }, ); • sub callback { print "method got tick...n" } } Thing->new()->run_all();
  • 72. Method Callbacks method got tick... method got tick... method got tick... method got tick... method got tick... method got tick... method got tick... method got tick... method got tick... method got tick... ^C
  • 73. Methods – The Costs • Verbose syntax. • Perl OO is slower than code references and closures. • Perl OO requires memory. • Moose uses memory, too.
  • 74. Methods – The Benefits • Syntax gets sweeter. • Object oriented design is cleaner and more extensible. • No twisty maze of nested code references, all different. • It’s all “standard” Perl and/or Moose.
  • 75. Methods – The Future • Avoiding flexibility by design is a dead end. • Speed and size improve over time. • Perl may get its own MOP. • Moose and Moose-alikes may converge as Perl standardizes common features.
  • 78. What’s a Promise? “an object that acts as a proxy for a result that is initially not known, usually because the computation of its value has not yet completed.” — Wikipedia
  • 80. Promises • Asynchronous event generator. • Create it. • Do other stuff while it’s working. • Pick up the next result later. • Blocks or returns “incomplete” if not done. • Implementation decides which. • Future release may let the caller decide.
  • 81. Timer Promise (1 of 2) use Reflex::Interval; • my $one = Reflex::Interval->new( • interval => 1 • ); my $two = Reflex::Interval->new( interval => 2 );
  • 82. Timer Promise (1 of 2) use Reflex::Interval; my $one = Reflex::Interval->new( interval => 1 ); • my $two = Reflex::Interval->new( • interval => 2 • );
  • 83. Timer Promise (2 of 2) print "Before : ", time(), "n"; • my $event = $two->next(); • print "After two: ", time(), "n"; $event = $one->next(); print "After one: ", time(), "n";
  • 84. Timer Promise (2 of 2) print "Before : ", time(), "n"; my $event = $two->next(); print "After two: ", time(), "n"; • $event = $one->next(); • print "After one: ", time(), "n";
  • 85. Eventy Timer Promise % perl promises.pl • Before : 1295045065 Blocked 2 seconds. • After two: 1295045067 After one: 1295045067
  • 86. Eventy Timer Promise % perl promises.pl Before : 1295045065 • After two: 1295045067 Instant result. • After one: 1295045067
  • 87. When to Avoid! Shun! • Only use Reflex’s promises for asynchronous tasks that may need to wait. • Synchronous generators and iterators are more efficient for computation.
  • 88. “We were somewhere around Asheville in the heart of the Blue Ridge Mountains when the Moose began to take hold.”
  • 90. Simpler Method Callbacks
  • 91. Method Callbacks { package TickingThing; use Moose; extends "Reflex::Base"; use Reflex::Interval; • has ticker => ( • isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( interval => 1, on_tick => [ $self, "callback" ], ) }, ); sub callback { print "method got tick...n" } } Thing->new()->run_all();
  • 92. Method Callbacks { package TickingThing; use Moose; extends "Reflex::Base"; use Reflex::Interval; has ticker => ( isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( • interval => 1, on_tick => [ $self, "callback" ], ) }, ); • sub callback { print "method got tick...n" } } Thing->new()->run_all();
  • 93. Method Callbacks { package TickingThing; use Moose; extends "Reflex::Base"; use Reflex::Interval; has ticker => ( isa => "Reflex::Interval", is => "rw", default => sub { my $self = shift(); Reflex::Interval->new( interval => 1, on_tick => [ $self, "callback" ], ) }, ); sub callback { print "method got tick...n" } } • Thing->new()->run_all();
  • 94. Subclassed Interval { • package TickingThing; use Moose; • extends "Reflex::Interval"; before on_tick => sub { print "customized tick...n" }; } TickingThing->new( interval => 1 )->run_all();
  • 95. Subclassed Interval { package TickingThing; use Moose; extends "Reflex::Interval"; • before on_tick => sub { • print "customized tick...n" }; } TickingThing->new( interval => 1 )->run_all();
  • 96. Subclassed Interval { package TickingThing; use Moose; extends "Reflex::Interval"; before on_tick => sub { print "customized tick...n" }; } • TickingThing->new( interval => 1 )->run_all();
  • 97. Roles
  • 98. Roles • They’re sticky. • They’re delicious. • They’re high in carbohydrate calories. • They may contain bacon.
  • 99. Reflex Roles • Eventy features are implemented as roles. • Consume them when appropriate. • Each role has a corresponding class. • Reflex::Interval is Reflex::Role::Interval.
  • 100. Reflex::Interval (1 of 3) package Reflex::Interval; use Moose; extends "Reflex::Base"; • has interval => ( isa => "Num", is => "rw" ); • has auto_repeat => ( isa => "Bool", is => "ro", default => 1 ); • has auto_start => ( isa => "Bool", is => "ro", default => 1 );
  • 101. Reflex::Interval (2 of 3) with "Reflex::Role::Interval" => { • att_interval => "interval", • att_auto_start => "auto_start", • att_auto_repeat => "auto_repeat", cb_tick => "on_tick", method_start => "start", method_stop => "stop", method_repeat => "repeat", }; sub on_tick { my ($self, $args) = @_; $self->emit( event => "tick", args => $args ); }
  • 102. Reflex::Interval (2 of 3) with "Reflex::Role::Interval" => { att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", • cb_tick => "on_tick", method_start => "start", method_stop => "stop", method_repeat => "repeat", }; • sub on_tick { my ($self, $args) = @_; • $self->emit( • event => "tick", args => $args ); }
  • 103. Reflex::Interval (2 of 3) with "Reflex::Role::Interval" => { att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", cb_tick => "on_tick", • method_start => "start", • method_stop => "stop", • method_repeat => "repeat", }; sub on_tick { my ($self, $args) = @_; $self->emit( event => "tick", args => $args ); }
  • 105. Parameterized Roles • Reflex uses role parameters to wire together code. • MooseX::Role:: Parameterized rocks for this.
  • 106. Three Kinds of Role Parameters
  • 107. Attribute Parameters • Name attributes in the consumer that control role behavior. • Begin with “att_”.
  • 108. Attribute Parameters package Reflex::Interval; use Moose; • has interval => ( isa => "Num", ... ); • has auto_start => ( isa => "Bool", ... ); ...; with "Reflex::Role::Interval" => { att_interval => "interval", att_auto_start => "auto_start", ..., };
  • 109. Attribute Parameters package Reflex::Interval; use Moose; has interval => ( isa => "Num", ... ); has auto_start => ( isa => "Bool", ... ); ...; with "Reflex::Role::Interval" => { • att_interval => "interval", • att_auto_start => "auto_start", ..., };
  • 110. Callback Parameters • Name consumer methods to call back when things happen. • Begin with “cb_”. • These callbacks are simple, synchronous method calls.
  • 111. Callback Parameters package Reflex::Interval; use Moose; ...; with "Reflex::Role::Interval" => { • cb_tick => "on_tick", ..., }; • sub on_tick { my ($self, $args_hash) = @_; ...; }
  • 112. Method Parameters • Roles may implement public API methods. • Classes get to decide what they’re called. • Begin with “method_”.
  • 113. Method Parameters { package Reflex::Interval; use Moose; extends "Reflex::Base"; with "Reflex::Role::Interval" => { ..., • method_start => "start", • method_stop => "stop", }; } my $interval = Reflex::Interval->new(); • $interval->stop(); • $interval->start();
  • 114. Lots of Role Parameters
  • 115. Awesome but tedious to configure.
  • 116. Dynamic Defaults • Each role designates a primary attribute parameter. • Other parameter default values are based on the primary parameter’s value. • Avoids namespace clashes as an extension of basic OO.
  • 117. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "watchdog", ..., } Role Parameter Default Name method_start start_watchdog() method_stop stop_watchdog() cb_tick on_watchdog_tick()
  • 118. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "log_rotation", ..., } Role Parameter Default Name method_start start_log_rotation() method_stop stop_log_rotation() cb_tick on_log_rotation_tick()
  • 119. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "interval", • att_auto_start => "auto_start", • att_auto_repeat => "auto_repeat", • cb_tick => "on_tick", • method_start => "start", • method_stop => "stop", • method_repeat => "repeat", }; Redundancy is a special case. It overrides generally useful defaults.
  • 120. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", • cb_tick => "on_tick", method_start => "start", method_stop => "stop", method_repeat => "repeat", }; Calls $self->on_tick() ... not $self->on_interval_tick()
  • 121. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", cb_tick => "on_tick", • method_start => "start", method_stop => "stop", method_repeat => "repeat", }; Creates $interval->start() ... not $interval->start_interval()
  • 122. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", cb_tick => "on_tick", method_start => "start", • method_stop => "stop", method_repeat => "repeat", }; Creates $interval->stop() ... not $interval->stop_interval()
  • 123. Primary Attribute with "Reflex::Role::Interval" => { • att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", cb_tick => "on_tick", method_start => "start", method_stop => "stop", • method_repeat => "repeat", }; Etc.
  • 126. Expose Inner Workings { • package AnotherTickingThing; • use Moose; extends "TickingThing"; has "+ticker" => ( handles => [ "interval" ], ); } my $thing = AnotherTickingThing->new(); $thing->interval(0.1); $thing->run_all();
  • 127. Expose Inner Workings { package AnotherTickingThing; use Moose; extends "TickingThing"; • has "+ticker" => ( • handles => [ "interval" ], • ); } my $thing = AnotherTickingThing->new(); $thing->interval(0.1); $thing->run_all();
  • 128. Expose Inner Workings { package AnotherTickingThing; use Moose; extends "TickingThing"; has "+ticker" => ( handles => [ "interval" ], ); } my $thing = AnotherTickingThing->new(); • $thing->interval(0.1); $thing->run_all();
  • 130. Replace Inner Workings my $thing = TickingThing->new(); • $thing->ticker( • Reflex::Interval->new( • interval => 0.125, on_tick => [ $thing, "callback" ], ) ); $thing->run_all();
  • 131. Replace Inner Workings • my $thing = TickingThing->new( ticker => Reflex::Interval->new( interval => 0.125, • on_tick => [ $thing, "callback" ], ) ); Can’t use $thing like this. It must be declared before it can be used.
  • 132. Replace Inner Workings • my $thing; • $thing = TickingThing->new( ticker => Reflex::Interval->new( interval => 0.125, • on_tick => [ $thing, "callback" ], ) ); Two statements. Reference to $thing held inside $thing.
  • 133. Replace Inner Workings • my $thing = TickingThing->new(); • $thing->ticker( Reflex::Interval->new( interval => 0.125, • on_tick => [ $thing, "callback" ], ) ); Dynamically replace it later. Reference to $thing held inside $thing.
  • 134. Replace Inner Workings my $thing = TickingThing->new(); $thing->ticker( Reflex::Interval->new( interval => 0.125, • on_tick => [ $thing, "callback" ], ) ); Either way, Reflex automatically weakens the inner reference for you.
  • 136. Override Attributes { • package FasterInterval; • use Moose; extends "Reflex::Interval"; has "+interval" => ( default => 0.5, ); } FasterInterval->new()->run_all();
  • 137. Override Attributes { package FasterInterval; use Moose; extends "Reflex::Interval"; • has "+interval" => ( • default => 0.5, ); } FasterInterval->new()->run_all();
  • 138. Override Attributes { package FasterInterval; use Moose; extends "Reflex::Interval"; has "+interval" => ( default => 0.5, ); } • FasterInterval->new()->run_all();
  • 141. Reflex How does it work? Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime
  • 142. Static Reflex = Moose
  • 143. Dynamic Reflex = Emit & Watch
  • 144. Crossing the Barrier Between Static & Dynamic Interaction
  • 145. Static to Dynamic • Classes are built using static roles. • Classes implement additional features. • Callbacks within a class are synchronous. • Classes emit dynamic messages. • Dynamic object interaction is based on watching for those messages.
  • 146. Default Callback with "Reflex::Role::Interval" => { att_interval => "interval", att_auto_start => "auto_start", att_auto_repeat => "auto_repeat", • cb_tick => "on_tick", method_start => "start", method_stop => "stop", method_repeat => "repeat", }; • sub on_tick { my ($self, $args) = @_; • $self->emit( • event => "tick", args => $args ); }
  • 147. Dynamic back to Static? Just Call Stuff, Okay?
  • 148. Trade Offs • Dynamic object interaction is richer, more fun, and often necessary. • Beware of using dynamic messages solely “for fun’s sake”. • Static callbacks are more efficient.
  • 149. Emitting an Event • package Moosian; use Moose; • extends "Reflex::Base"; has name => ( is => "ro", isa => "Str" ); sub yip { my ($self, $args) = @_; print( $self->name(), " says: Yip-yip-yip-yip..", " uh-huh uh-huh..n" ); $self->emit( event => "yipped" ); } 1;
  • 150. Emitting an Event package Moosian; use Moose; extends "Reflex::Base"; has name => ( is => "ro", isa => "Str" ); • sub yip { my ($self, $args) = @_; • print( • $self->name(), • " says: Yip-yip-yip-yip..", • " uh-huh uh-huh..n" • ); $self->emit( event => "yipped" ); } 1;
  • 151. Emitting an Event package Moosian; use Moose; extends "Reflex::Base"; has name => ( is => "ro", isa => "Str" ); sub yip { my ($self, $args) = @_; print( $self->name(), " says: Yip-yip-yip-yip..", " uh-huh uh-huh..n" ); • $self->emit( event => "yipped" ); } 1;
  • 152. Emitting Events • Objects emit() events as part of their public interfaces. • Events have no explicit destination. • It’s up to users to watch() for events.
  • 153. Watching Events • my $bob = Moosian->new( name => "Bob" ); my $joe = Moosian->new( name => "Joe" ); • $bob->watch( $joe, "yipped", "yip" ); $joe->watch( $bob, "yipped", "yip" ); $bob->yip(); Reflex->run_all();
  • 154. Watching Events my $bob = Moosian->new( name => "Bob" ); • my $joe = Moosian->new( name => "Joe" ); $bob->watch( $joe, "yipped", "yip" ); • $joe->watch( $bob, "yipped", "yip" ); $bob->yip(); Reflex->run_all();
  • 155. Watching Events my $bob = Moosian->new( name => "Bob" ); my $joe = Moosian->new( name => "Joe" ); $bob->watch( $joe, "yipped", "yip" ); $joe->watch( $bob, "yipped", "yip" ); • $bob->yip(); • Reflex->run_all();
  • 156. Moosian Dialog Bob says: Yip-yip-yip-yip... uh-huh uh-huh.. Joe says: Yip-yip-yip-yip... uh-huh uh-huh.. Bob says: Yip-yip-yip-yip... uh-huh uh-huh.. Joe says: Yip-yip-yip-yip... uh-huh uh-huh.. Bob says: Yip-yip-yip-yip... uh-huh uh-huh.. Joe says: Yip-yip-yip-yip... uh-huh uh-huh.. Bob says: Yip-yip-yip-yip... uh-huh uh-huh.. Joe says: Yip-yip-yip-yip... uh-huh uh-huh.. Bob says: Yip-yip-yip-yip... uh-huh uh-huh.. Joe says: Yip-yip-yip-yip... uh-huh uh-huh.. ^C
  • 157. Infinite Recursion OK TIME RSS COMMAND • 1:16.60 17940 perl moosians.pl TIME RSS COMMAND 2:37.94 17940 perl moosians.pl TIME RSS COMMAND 3:05.86 17940 perl moosians.pl TIME RSS COMMAND 3:30.69 17940 perl moosians.pl
  • 158. Infinite Recursion OK TIME RSS COMMAND 1:16.60 17940 perl moosians.pl TIME RSS COMMAND • 2:37.94 17940 perl moosians.pl TIME RSS COMMAND 3:05.86 17940 perl moosians.pl TIME RSS COMMAND 3:30.69 17940 perl moosians.pl
  • 159. Infinite Recursion OK TIME RSS COMMAND 1:16.60 17940 perl moosians.pl TIME RSS COMMAND 2:37.94 17940 perl moosians.pl TIME RSS COMMAND • 3:05.86 17940 perl moosians.pl TIME RSS COMMAND 3:30.69 17940 perl moosians.pl
  • 160. Infinite Recursion OK TIME RSS COMMAND 1:16.60 17940 perl moosians.pl TIME RSS COMMAND 2:37.94 17940 perl moosians.pl TIME RSS COMMAND 3:05.86 17940 perl moosians.pl TIME RSS COMMAND • 3:30.69 17940 perl moosians.pl
  • 162. Hierarchical Watching? • Most program structure is hierarchical. • Trees of objects that use other objects. • Parent objects often need results from children.
  • 163. Moose Traits Rock
  • 166. Watched Attributes • use Reflex::Trait::Watched qw(watches); • watches clock => ( isa => "Reflex::Interval", setup => sub { Reflex::Interval->new(interval => 1) }, ); sub on_clock_tick { print "tick...n" }
  • 167. Watched Attributes use Reflex::Trait::Watched qw(watches); watches clock => ( isa => "Reflex::Interval", setup => sub { Reflex::Interval->new(interval => 1) }, ); • sub on_clock_tick { print "tick...n" }
  • 168. Watched Attributes use Reflex::Trait::Watched qw(watches); watches clock => ( isa => "Reflex::Interval", setup => sub { Reflex::Interval->new(interval => 1) }, ); • sub on_clock_tick { print "tick...n" }
  • 169. Watched Attributes use Reflex::Trait::Watched qw(watches); • watches clock => ( isa => "Reflex::Interval", setup => sub { Reflex::Interval->new(interval => 1) }, ); • sub on_clock_tick { print "tick...n" }
  • 170. Watched Attributes use Reflex::Trait::Watched qw(watches); watches clock => ( • isa => "Reflex::Interval", setup => sub { Reflex::Interval->new(interval => 1) }, ); • sub on_clock_tick { print "tick...n" }
  • 171. Watched Attributes use Reflex::Trait::Watched qw(watches); • watches penguin => ( • isa => "Reflex::Bomb", setup => sub { ... }, ); sub on_penguin_tick { ... } sub on_penguin_stop { ... } sub on_penguin_explode { ... }
  • 172. Watched Attributes use Reflex::Trait::Watched qw(watches); watches penguin => ( isa => "Reflex::Bomb", setup => sub { ... }, ); • sub on_penguin_tick { ... } • sub on_penguin_stop { ... } • sub on_penguin_explode { ... }
  • 173. Watched Attributes use Reflex::Trait::Watched qw(watches); • watches watchdog => ( ... Interval ... ); • watches log_mark => ( ... Interval ... ); • sub on_watchdog_tick { ... } • sub on_log_mark_tick { ... }
  • 175. Two-Way Pipe Driver • Bidirectionally stream data between two file handles. • Useful for proxies.
  • 176. Two File Handles • package Proxy; use Moose; extends "Reflex::Base"; • has client => ( • isa => "FileHandle", is => "rw", required => 1 ); • has server => ( • isa => "FileHandle", is => "rw", required => 1 ); • has active => ( • isa => "Bool", is => "ro", default => 1 );
  • 177. Reduced for Example • use Reflex::Callbacks "make_null_handler"; • make_null_handler("on_client_closed"); • make_null_handler("on_client_error"); • make_null_handler("on_server_closed"); • make_null_handler("on_server_error");
  • 178. From Client to Server • with "Reflex::Role::Streaming" => { att_active => "active", • att_handle => "client", }; sub on_client_data { my ($self, $arg) = @_; $self->put_server($arg->{data}); }
  • 179. From Client to Server with "Reflex::Role::Streaming" => { att_active => "active", att_handle => "client", }; • sub on_client_data { my ($self, $arg) = @_; • $self->put_server($arg->{data}); }
  • 180. From Server to Client • with "Reflex::Role::Streaming" => { att_active => "active", • att_handle => "server", }; sub on_server_data { my ($self, $arg) = @_; $self->put_client($arg->{data}); }
  • 181. From Server to Client with "Reflex::Role::Streaming" => { att_active => "active", att_handle => "server", }; • sub on_server_data { my ($self, $arg) = @_; • $self->put_client($arg->{data}); }
  • 183. Quote-Done-Unquote • Not handling EOF (cb_closed). • Not handling errors (cb_error). • We’ll probably need separate “active” flags for client and server later. • Flow-control for data rate mismatches? • Etc.
  • 184. Usage # Assume we already have the sockets. • my $p = Proxy->new( • client => $client_socket, • server => $server_socket, ); # Do something else while it runs.
  • 186. I Wrote What? Reflex::Role::Writable att_handle Reflex::Role::Reading att_active att_handle cb_ready cb_closed method_pause cb_data method_resume cb_error method_start method_read Reflex::Role::Readable Reflex::Role::Writing method_stop att_handle att_handle att_active cb_error cb_ready method_put method_pause method_flush Proxy method_resume client method_stop server Reflex::Role::Streaming active Reflex::Role::Streaming att_handle on_client_data att_handle att_active on_client_closed att_active cb_data on_client_error cb_data cb_closed put_client cb_closed cb_error stop_client cb_error method_put on_server_data method_put method_stop on_server_closed method_stop on_server_error Reflex::Role::Readable put_server att_handle stop_server Reflex::Role::Writing att_active att_handle cb_ready cb_error method_pause method_put Reflex::Role::Writable method_resume method_flush Reflex::Role::Reading att_handle method_stop att_handle att_active cb_closed cb_ready cb_data method_pause cb_error method_resume method_read method_start method_stop
  • 187. Reflex::Role::Streaming Reflex The ability to.... Role Reading ... read data from a non-blocking file handle. Readable ... watch for data arriving on a file handle. Writing ... buffer and/or write data to a NB file handle. Writable ... watch a file handle for ability to write data.
  • 188. Relax–It’s Just the Class • That’s the Proxy class. • All instances will share the same code.
  • 189. Overkill? Dial it Back! Roles let programs pick and mix what they need.
  • 190. Reflex::Role::InStreaming Reflex::Role::InStreaming att_handle att_active cb_data cb_closed cb_error method_stop Reflex::Role::Readable Reflex::Role::Reading att_handle att_handle att_active cb_closed cb_ready cb_data method_pause cb_error method_resume method_read method_stop
  • 191. Reflex::Role::OutStreaming Reflex::Role::OutStreaming att_handle att_active cb_data cb_closed cb_error method_put method_stop Reflex::Role::Writable att_handle Reflex::Role::Writing att_active att_handle cb_ready cb_error method_pause method_put method_resume method_flush method_start method_stop
  • 194. Auto-Emit Messages When Attributes Change
  • 195. SmallTalk Messaging • package EmittingCounter; • use Reflex::Trait::EmitsOnChange qw(emits); emits count => ( isa => "Int", default => 0 ); sub something_happens { my $self = shift; $self->count($self->count() + 1); }
  • 196. SmallTalk Messaging package EmittingCounter; use Reflex::Trait::EmitsOnChange qw(emits); • emits count => ( isa => "Int", default => 0 ); sub something_happens { my $self = shift; • $self->count($self->count() + 1); }
  • 197. Now Watch It • use EmittingCounter; use Reflex::Trait::Watched qw(watches); • watches counter => ( • isa => "EmittingCounter", setup => sub { EmittingCounter-> new() }, ); sub on_counter_count { my ($self, $args) = @_; print "counter reached $args->{value}n"; }
  • 198. Now Watch It use EmittingCounter; use Reflex::Trait::Watched qw(watches); watches counter => ( isa => "EmittingCounter", setup => sub { EmittingCounter-> new() }, ); • sub on_counter_count { my ($self, $args) = @_; • print "counter reached $args->{value}n"; }
  • 200. Reflex::Collection • Manages objects that do Reflex::Role::Collectible. • Collectible objects are automatically cleaned up when they stop. • Great for create-and-forget things.
  • 201. Echo Server (1 of 1) { • package TcpEchoServer; use Moose; • extends "Reflex::Acceptor"; use EchoStream; use Reflex::Collection qw(has_many); has_many clients => ( handles => { remember_client => "remember" } ); sub on_accept { my ($self, $args) = @_; $self->remember_client( EchoStream->new( handle => $args->{socket} ) ); } }
  • 202. Echo Server (1 of 1) { package TcpEchoServer; use Moose; • extends "Reflex::Acceptor"; use EchoStream; use Reflex::Collection qw(has_many); has_many clients => ( handles => { remember_client => "remember" } ); sub on_accept { my ($self, $args) = @_; $self->remember_client( EchoStream->new( handle => $args->{socket} ) ); } }
  • 203. Echo Server (1 of 1) { package TcpEchoServer; use Moose; extends "Reflex::Acceptor"; use EchoStream; • use Reflex::Collection qw(has_many); has_many clients => ( handles => { remember_client => "remember" } ); sub on_accept { my ($self, $args) = @_; $self->remember_client( EchoStream->new( handle => $args->{socket} ) ); } }
  • 204. Echo Server (1 of 1) { package TcpEchoServer; use Moose; extends "Reflex::Acceptor"; use EchoStream; use Reflex::Collection qw(has_many); • has_many clients => ( • handles => { • remember_client => "remember" } ); sub on_accept { my ($self, $args) = @_; $self->remember_client( EchoStream->new( handle => $args->{socket} ) ); } }
  • 205. Echo Server (1 of 1) { package TcpEchoServer; use Moose; extends "Reflex::Acceptor"; use EchoStream; use Reflex::Collection qw(has_many); has_many clients => ( handles => { remember_client => "remember" } ); • sub on_accept { my ($self, $args) = @_; • $self->remember_client( • EchoStream->new( handle => $args->{socket} ) ); } }
  • 206. EchoStream (1 of 1) • package EchoStream; use Moose; • extends "Reflex::Stream"; sub on_data { my ($self, $args) = @_; $self->put($args->{data}); } 1;
  • 207. EchoStream (1 of 1) package EchoStream; use Moose; extends "Reflex::Stream"; • sub on_data { my ($self, $args) = @_; • $self->put($args->{data}); } 1;
  • 209. Benefits of POE • Mature and stable. • Use any event loop you want. • Hundreds of existing modules. • Thousands of users. • And you. • Don’t rewrite everything at once.
  • 210. POE Compatibility • Migrate incrementally. • Reflex can talk to POE modules. • POE modules can talk to Reflex objects. • “Separate but equal” is not enough. • Static Reflex is faster than POE message passing. • Reflex eg directory contains examples.
  • 211. “But is Reflex Ready?”
  • 212. 40% Complete! • Large swathes of design are stable. • Documentation! • ... which I broke preparing for this talk. • Bugs! • ... which I added preparing for this talk. • Roadmap documented in the repository.
  • 213. Help Make It Better • http://github.com/rcaputo/reflex • See the roadmap. • #reflex on irc.perl.org • poe-subscribe@perl.org • Hackathon, BOF or hallway track. • Use it, and complain... to me. • Influence the project while it’s still plastic.
  • 214. Contribute to a Project • Nick Perez’s Reflex-based psgi server. • Reflexive::Role::Collective Interact with a collection of reflexive objects. • Reflexive::Role::DataMover Move data between two streams. • Reflexive::Role::TCPServer Become a fully featured TCP server. • Reflexive::Stream::Filtering Apply POE filters to Reflex streams. • (Your Project Here)
  • 216. Webliography Drawing of Edgar Allan Self-Herding Cat Poe. ORM Diagram “A Softer World” comic. POE's users are Wizard Moose outstanding in their fields. Edgar Allan Bro Moose Antlers Universum Promise Ring Tiled Angry Moose The Watchers Accidental Goatse A Fighter Jet Made of (Unused) Biceps