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

Transcript
Page 1: Reflex - How Does It Work? (extended dance remix)

ReflexHow does it work?

Rocco Caputo – @rcaputoYAPC::NA

Tuesday, 28 June 2011Around Teatime

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

Feedback, plx.

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

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

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

“The POE Guy”

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

⃠“The POE Guy”⃠

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

Curtis “Ovid” Poe

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

Edgar Allan Poe

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

Anne Decatur

Danielewski

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

The Other Committers• Adam Kennedy

• Benjamin Smith

• Casey West

• Chris Fedde

• Chris Williams

• David Davis

• David Webb

• Hinrik Örn Sigurðsson

• jmadler

• Jonathan Steinert

• Larwan Berke

• Martijn van Beers

• Matt Cashner

• Matt Sickler

• Perl Whore

• Philip Gwyn

• Tom Feist

• Yuval Kogman

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

The CPAN AuthorsAlejandro 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 • [email protected] • William Travis Holton • Yuji Suzuki • Yves Blusseau • Zoffix Znet

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

EOVERFLOWThe Users

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

Okay, me too.

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

Digression:See Digression

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

ReflexWhat Is It?

Rocco Caputo – @rcaputoYAPC::NA

Tuesday, 28 June 2011Around Teatime

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

ReflexWhat Isn’t It?

Rocco Caputo – @rcaputoYAPC::NA

Tuesday, 28 June 2011Around Teatime

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

What can’t you do with a drunken sailor?

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

Reflex is an only child waiting in

the park.

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

⃠Reflex is an only child waiting in

the park.⃠

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

Reflex isn’t an event loop.

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

CPAN already has too many

event loops.

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

Event loops are the means, not the ends.

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

Reflex is eventy without so much loopy.

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

Nor is Reflex an object system.

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

CPAN already has too many

object systems.

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

Reflex uses Moose

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

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

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

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.

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

ReflexWhat Is It?

Rocco Caputo – @rcaputoYAPC::NA

Tuesday, 28 June 2011Around Teatime

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

The ORM of Event Loops!!

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

Marketing bullshit aside...

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

Reactive Program Building

Blocks

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

Building Blocks

Provided by Moose

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

Plus a Reactor provided by Your Favorite Event

Loop

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

Invisible Event Loop

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

Like ORMs hide SQL behind

objects...

ORM

DB

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

Reflex

The Events Can

Reflex hides event

loops behind

objects...

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

Reflex is Modern

POE

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

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.

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

Reflex unifies eventy

interaction.

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

Rule 34 for Perl

If you can think of it, CPAN has a module for it.

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

TIMTOWTDI

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

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

TIMTOWTDI

... and someday you’ll need to

use both at once.

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

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.

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

3 ½ Rules Make it Work

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

⁓ 1 ⁓Objects must not dictate callback mechanisms.

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

⁓ 1.5 ⁓Users define

how they receive callbacks.

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

⁓ 2 ⁓The base system must support all desired callback

types.

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

⁓ 3 ⁓Reflex must do

just enough work to be correct.

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

Reflex unifies eventy program

composition.

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

“How Eventy Programs are Put Together”

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

Static Composition

• Code is bolted together before running.

• Subclassing.

• Role composition.

• All pieces built and destroyed together.

• Most eventy abstractions ignore this.

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

Dynamic Composition

• Event watchers are created,

• related (has-a),

• communicated (with),

• and destructicated

• at run time.

• Lather, rinse, repeat until the owner ends.

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

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.

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

Reflex Embraces,

Extends and Consumes Both

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

Examples are next.

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

ReflexHow to Use It!

Rocco Caputo – @rcaputoYAPC::NA

Tuesday, 28 June 2011Around Teatime

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

Anonymous Callbacks

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

Ye Olde Coderefuse 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();

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

Ye Olde Coderefuse 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();

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

Ye Olde Coderefuse 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();

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

Ye Olde Coderefuse 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();

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

tick one...TICK TWO!!!TICK TWO!!!tick one...TICK TWO!!!TICK TWO!!!tick one...TICK TWO!!!TICK TWO!!!^C

Ye Olde Coderef

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

Ye Olde Coderef - The Good

• Quick and dead simple to use.

• Convenient and fast for small things.

• Parsimonious use of memory.

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

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.

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

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 {

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

Method Callbacks

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

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();

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

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();

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

{ 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

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

{ 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

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

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

Method Callbacks

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

Methods – The Costs

• Verbose syntax.

• Perl OO is slower than code references and closures.

• Perl OO requires memory.

• Moose uses memory, too.

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

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.

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

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.

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

“But callbacks suck!” you say?

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

Promises

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

“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?

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

What’s a Promise?

Blah, blah, blah.

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

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.

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

use Reflex::Interval;

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

my $two = Reflex::Interval->new( interval => 2);

Timer Promise (1 of 2)

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

use Reflex::Interval;

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

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

Timer Promise (1 of 2)

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

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)

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

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)

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

% perl promises.pl • Before : 1295045065• After two: 1295045067

After one: 1295045067

Eventy Timer Promise

Blocked 2 seconds.

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

% perl promises.pl Before : 1295045065

• After two: 1295045067• After one: 1295045067

Eventy Timer Promise

Instant result.

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

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.

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

“We were somewhere around Asheville in the

heart of the Blue Ridge Mountains when the Moose began to

take hold.”

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

Subclassing

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

Simpler Method Callbacks

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

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();

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

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();

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

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();

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

Subclassed Interval

{• package TickingThing;

use Moose;• extends "Reflex::Interval";

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

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

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

Subclassed Interval

{ package TickingThing; use Moose; extends "Reflex::Interval";

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

};}

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

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

Subclassed Interval

{ package TickingThing; use Moose; extends "Reflex::Interval";

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

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

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

Roles

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

Roles

• They’re sticky.

• They’re delicious.

• They’re high in carbohydrate calories.

• They may contain bacon.

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

Reflex Roles

• Eventy features are implemented as roles.

• Consume them when appropriate.

• Each role has a corresponding class.

• Reflex::Interval is Reflex::Role::Interval.

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

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);

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

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 );}

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

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

);}

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

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 );}

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

1;Reflex::Interval (3 of 3)

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

Parameterized Roles

• Reflex uses role parameters to wire together code.

• MooseX::Role:: Parameterized rocks for this.

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

Three Kinds of Role Parameters

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

Attribute Parameters

• Name attributes in the consumer that control role behavior.

• Begin with “att_”.

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

Attribute Parameterspackage 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", ...,};

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

Attribute Parameterspackage 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",

...,};

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

Callback Parameters

• Name consumer methods to call back when things happen.

• Begin with “cb_”.

• These callbacks are simple, synchronous method calls.

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

Callback Parameterspackage Reflex::Interval;use Moose;...;

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

...,};

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

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

Method Parameters

• Roles may implement public API methods.

• Classes get to decide what they’re called.

• Begin with “method_”.

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

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();

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

Lots of Role

Parameters

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

Awesome but

tedious to configure.

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

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.

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

Primary Attributewith "Reflex::Role::Interval" => {

• att_interval => "watchdog", ...,}

Role Parameter Default Name

method_start start_watchdog()

method_stop stop_watchdog()

cb_tick on_watchdog_tick()

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

Primary Attributewith "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()

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

Primary Attributewith "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.

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

Primary Attributewith "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()

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

Primary Attributewith "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()

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

Primary Attributewith "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()

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

Primary Attributewith "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.

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

Other Moose Magic

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

Expose Inner Workings

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

Expose Inner Workings{

• package AnotherTickingThing;• use Moose; extends "TickingThing";

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

my $thing = AnotherTickingThing->new();$thing->interval(0.1);$thing->run_all();

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

Expose Inner Workings{ package AnotherTickingThing; use Moose; extends "TickingThing";

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

}

my $thing = AnotherTickingThing->new();$thing->interval(0.1);$thing->run_all();

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

Expose Inner Workings{ package AnotherTickingThing; use Moose; extends "TickingThing";

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

my $thing = AnotherTickingThing->new();• $thing->interval(0.1);

$thing->run_all();

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

Replace Inner Workings

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

Replace Inner Workings

my $thing = TickingThing->new();

• $thing->ticker(• Reflex::Interval->new(• interval => 0.125,

on_tick => [ $thing, "callback" ], ));

$thing->run_all();

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

• my $thing = TickingThing->new( ticker => Reflex::Interval->new( interval => 0.125,

• on_tick => [ $thing, "callback" ], ));

Replace Inner Workings

Can’t use $thing like this.It must be declared before it can be used.

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

Two statements.Reference to $thing held inside $thing.

Replace Inner Workings

• my $thing;• $thing = TickingThing->new(

ticker => Reflex::Interval->new( interval => 0.125,

• on_tick => [ $thing, "callback" ], ));

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

• 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

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

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.

Replace Inner Workings

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

Override Attributes

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

Override Attributes

{• package FasterInterval;• use Moose; extends "Reflex::Interval";

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

FasterInterval->new()->run_all();

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

Override Attributes

{ package FasterInterval; use Moose; extends "Reflex::Interval";

• has "+interval" => (• default => 0.5,

);}

FasterInterval->new()->run_all();

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

Override Attributes

{ package FasterInterval; use Moose; extends "Reflex::Interval";

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

• FasterInterval->new()->run_all();

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

Whatever Objects Can Do

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

What Can’t Objects Do?

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

ReflexHow does it work?

Rocco Caputo – @rcaputoYAPC::NA

Tuesday, 28 June 2011Around Teatime

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

Static Reflex=

Moose

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

Dynamic Reflex

=Emit & Watch

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

Crossing the Barrier Between Static & Dynamic

Interaction

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

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.

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

Default Callbackwith "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

);}

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

Dynamic back to Static?

Just Call Stuff, Okay?

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

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.

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

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;

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

Emitting an Eventpackage 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;

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

Emitting an Eventpackage 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;

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

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.

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

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();

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

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();

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

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();

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

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

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

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

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

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

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

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

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

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

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

Simplified Hierarchical Watching

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

Hierarchical Watching?• Most program

structure is hierarchical.

• Trees of objects that use other objects.

• Parent objects often need results from children.

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

Moose Traits Rock

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

Watched Attributes

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

Callbacks Discovered by

Name

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

• 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• watches watchdog => ( ... Interval ... );• watches log_mark => ( ... Interval ... );

• sub on_watchdog_tick { ... }• sub on_log_mark_tick { ... }

Watched Attributes

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

Reflex Role Composition

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

Two-Way Pipe Driver

• Bidirectionally stream data between two file handles.

• Useful for proxies.

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

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 );

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

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");

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

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});}

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

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});}

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

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});}

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

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});}

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

1;We’re “Done”

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

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.

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

Usage

# Assume we already have the sockets.

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

);

# Do something else while it runs.

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

Simple?

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

I Wrote What?

on_client_dataon_client_closedon_client_errorput_clientstop_clienton_server_dataon_server_closedon_server_errorput_serverstop_server

clientserveractive

Proxy

att_handleatt_activecb_datacb_closedcb_errormethod_putmethod_stop

Reflex::Role::Streaming

cb_readymethod_pausemethod_resumemethod_startmethod_stop

att_handleatt_active

Reflex::Role::Writable

cb_errormethod_putmethod_flush

att_handleReflex::Role::Writing

cb_readymethod_pausemethod_resumemethod_stop

att_handleatt_active

Reflex::Role::Readable

cb_closedcb_datacb_errormethod_read

att_handleReflex::Role::Reading

att_handleatt_activecb_datacb_closedcb_errormethod_putmethod_stop

Reflex::Role::Streaming

cb_readymethod_pausemethod_resumemethod_startmethod_stop

att_handleatt_active

Reflex::Role::Writablecb_errormethod_putmethod_flush

att_handleReflex::Role::Writing

cb_readymethod_pausemethod_resumemethod_stop

att_handleatt_active

Reflex::Role::Readable

cb_closedcb_datacb_errormethod_read

att_handleReflex::Role::Reading

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

Reflex::Role::StreamingReflex Role The ability to....

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.

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

Relax–It’s Just the Class

• That’s the Proxy class.

• All instances will share the same code.

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

Overkill? Dial it Back!

Roles let programs pick and mix what

they need.

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

Reflex::Role::InStreaming

att_handleatt_activecb_datacb_closedcb_errormethod_stop

Reflex::Role::InStreaming

cb_readymethod_pausemethod_resumemethod_stop

att_handleatt_active

Reflex::Role::Readable

cb_closedcb_datacb_errormethod_read

att_handleReflex::Role::Reading

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

Reflex::Role::OutStreaming

att_handleatt_activecb_datacb_closedcb_errormethod_putmethod_stop

Reflex::Role::OutStreaming

cb_readymethod_pausemethod_resumemethod_startmethod_stop

att_handleatt_active

Reflex::Role::Writable

cb_errormethod_putmethod_flush

att_handleReflex::Role::Writing

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

Dynamic Fun

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

SmallTalk-Like Messaging

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

Auto-Emit Messages When

Attributes Change

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

• 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

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

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

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

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";}

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

Now Watch Ituse 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";}

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

Self-Managed

Collections

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

Reflex::Collection

• Manages objects that do Reflex::Role::Collectible.

• Collectible objects are automatically cleaned up when they stop.

• Great for create-and-forget things.

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

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} ) ); }}

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

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} ) ); }}

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

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} ) ); }}

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

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} ) ); }}

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

{ 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)

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

EchoStream (1 of 1)

• package EchoStream;use Moose;

• extends "Reflex::Stream";

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

1;

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

EchoStream (1 of 1)

package EchoStream;use Moose;extends "Reflex::Stream";

• sub on_data { my ($self, $args) = @_;

• $self->put($args->{data});}

1;

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

POE Compatibility

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

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.

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

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.

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

“But is Reflex Ready?”

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

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.

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

Help Make It Better

• http://github.com/rcaputo/reflex

• See the roadmap.

• #reflex on irc.perl.org

[email protected]

• Hackathon, BOF or hallway track.

• Use it, and complain... to me.

• Influence the project while it’s still plastic.

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

Contribute to a Project• Nick Perez’s Reflex-based psgi server.

• Reflexive::Role::CollectiveInteract with a collection of reflexive objects.

• Reflexive::Role::DataMoverMove data between two streams.

• Reflexive::Role::TCPServerBecome a fully featured TCP server.

• Reflexive::Stream::FilteringApply POE filters to Reflex streams.

• (Your Project Here)

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

Thank you!

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

WebliographyDrawing of Edgar Allan Poe.

“A Softer World” comic.

Wizard Moose

Edgar Allan Bro

Universum

Tiled Angry Moose

Accidental Goatse (Unused)

Self-Herding Cat

ORM Diagram

POE's users are outstanding in their fields.

Moose Antlers

Promise Ring

The Watchers

A Fighter Jet Made of Biceps