216
Reflex How does it work? Rocco Caputo – @rcaputo YAPC::NA Tuesday, 28 June 2011 Around Teatime

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

Embed Size (px)

DESCRIPTION

Most asynchronous Perl programming is unnecessarily dynamic. It conflicts with object orientation, and it reintroduces memory management issues that some of us learned Perl to escape.Reflex is a flexible, contemporary asynchronous library that embraces the latest developments in Perl object orientation. Asynchronous classes can be snapped together at coding time, reducing the amount of anonymous code that's often slung around at runtime. Methods are first-class callbacks in Reflex; they can be augmented and overridden using normal Perl OO. Mixing in Moose make things even better.This presentation is an expanded, more code-intensive version of my Perl Oasis talk. It will cover the 6.5 ways Reflex-based modules can be used, including anonymous callback and closure juggling, and mind-bogglingly powerful Moose-fueled OO crack. Imperative promises are included for people who just want to do one simple thing without mucking about with callbacks at all.

Citation preview

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