Browse files

Documentation reorganization.

Set up directories for current and old docs.  Revise currently relevant documentation, add new documentation, and move old documentation aside.
  • Loading branch information...
0 parents commit 25da785df71887706fd5f8f64d5a36011f46c970 @rcaputo committed Aug 6, 2009
Showing with 920 additions and 0 deletions.
  1. +275 −0 continuation-passing.otl
  2. +577 −0 patterns.otl
  3. +68 −0 requirements.otl
275 continuation-passing.otl
@@ -0,0 +1,275 @@
+ This document is outdated.
+ It discusses things in POE::Stage prior to the draft specification.
+ It will be updated after the specificatin's reasonably complete.
+ POE::Stage
+ Message-Based Continuations
+ Rocco Caputo
+ "... a sort of super-closure, one that remembers all the lexicals that were in scope when it was created, as well as remembering the call sequence you took to get there." -- Dan Sugalski
+Continuations Encapsulate Call
+ Specify where to resume on return.
+ Remember lexical state, so it can be restored on return.
+ Are passed to subroutines as just another parameter.
+Continuations Implement Return
+ Caller's execution resumes.
+ Caller's lexical state is restored.
+ Caller may receive some result from the returning method.
+POE::Request Encapsulates Call
+ Defines where to resume on return.
+ Remembers lexical state, so it can be restored on return.
+ Is passed as a message to another object.
+POE::Response Implements Return
+ Implicitly created when an inbound POE::Request is invoked.
+ |$inbound_request->return( ... );
+ Resumes caller's execution.
+ Caller's lexical state is restored.
+ May include results of a Stage's work.
+POE::Request Example
+ |my $outbound_request = POE::Request->new(
+ | stage => $target_stage_object,
+ | method => $target_method_name,
+ | args => \%maybe_some_parameters,
+ | on_success => \&resume_here_on_success,
+ | on_failure => \&or_here_on_failure,
+ |);
+POE::Response Return
+ |$inbound_request->return(
+ | type => "success", # could be "failure"
+ | args => \%maybe_some_return_values,
+ |);
+Typed Responses
+ Responses are typed.
+ Requests map response types to handlers.
+ Called Stages define an interface.
+ Callers use the interface.
+ Eliminates need for inside information.
+ Decouples Stages.
+ Permits dynamic flow control.
+Call Stacks
+ Limited to serial call/return.
+ Execution returns in order of call (LIFO).
+ one calls two
+ two calls three
+ three calls four
+ four returns to three
+ three returns to two
+ two returns to one
+Call Trees
+ Serial or parallel call/return.
+ Parallel returns occur in order of completion.
+ method 1 calls method 2
+ method 1 calls method 2 (again)
+ method 2a calls method 3a
+ method 2b calls method 3b
+ method 3b returns to method 2b
+ method 2b returns to method 1
+ method 3a returns to method 2a
+ method 2a returns to method 1
+Call Cancelation
+ Requests can be canceled before they return.
+ Sometimes you don't want to wait.
+ |my $outbound_request = POE::Request->new( ... );
+ |# ... later on:
+ |$outbound_request->cancel();
+Cancelation Effects
+ Prunes the call tree rooted at the canceled request.
+ Sub-requests (if any) canceled too.
+ Their remembered lexical states are destroyed.
+ Resources stored in those lexicals automatically freed.
+ Perl (not POE) GC rules apply here.
+Non-Final Returns
+ Returns don't have to be final.
+ Returns happen when a response is invoked.
+ Why can't a response be invoked more than once?
+ They can, but the name is different.
+ |# Many happy returns.
+ |$inbound_request->emit( type => "happy" );
+Final Returns
+ return() implies request is finished.
+ Implicitly triggers request destruction after delivery.
+ Calling return() twice is prohibited.
+ Also cannot emit() after return().
+Re-calling in Same Request
+ Parent can respond to emitter without a new continuation.
+ Simpler than POE::Request:
+ |$inbound_emit->recall(
+ | method => $target_method_name,
+ | args => \%maybe_some_more_parameters,
+ |);
+ (No target stage. Goes back to emitter.)
+ (No response type mapping. Inherited from original request.)
+ emit() and recall() implement two-way dialogue.
+ Can continue until return() or cancel().
+Lexical States
+ There can't be only one.
+ Lexical pad may contain data from three or more relevant states.
+ Prefixes identify different states.
+ Also prevent identical member names from colliding in the pad.
+ Prefixes don't affect member names.
+ |$prefix_member refers to "member".
+ @ and % sigils also supported.
+Inbound Request State
+ Temporary storage scoped to the inbound request.
+ Used as scratch space for handling the request.
+ Conveniently autodestructs when request is finalized.
+ Prefixed by "req_"
+ $req_member
+ @req_member
+ %req_member
+Outbound Request State
+ Temporary storage for data scoped to an outbound request.
+ Members exposed with expose().
+ Prefixes are arbitrary (but not reserved, duh).
+ |my $outbound_request = POE::Request->new( ... );
+ |expose $outbound_request => my $prefixed_member;
+ |$prefixed_member = "spay or neuter your pets";
+Inbound Response State
+ Only available inside emit() or return() handlers.
+ Recalls and mutates previously exposed outbound request state.
+ Prefixed with "rsp_".
+ |sub on_success {
+ | my $rsp_member; # "spay or neuter your pets"
+ |}
+Parameter State
+ So I can also stuff arguments into them.
+ Prefixed with "arg_"
+ $arg_thingy
+ @arg_thingy
+ %arg_thingy
+ Refer to the "thingy" argument, i.e.:
+ args => { thingy => "value" }
+Call Tree Revisited
+ Implemented by convention, not special code.
+ Sub-requests stored in the current request.
+ my $req_do_something = POE::Request->new( ... );
+ When current request finishes:
+ All $req_foo members destroyed.
+ Implicitly triggering $req_do_something cancelation.
+ Effectively pruning branch of call tree.
+Activating Lexical State
+ Only pertains to message handlers.
+ Activate with the :Handler method attribute.
+ sub resume_here_on_success :Handler { ... }
+ Also implied for methods named "on_" something.
+ Will be explained in a few slides.
+Request Roles Are Shorthand
+ Replace on_foo parameters in a request.
+ |my $req_subrequest = POE::Request->new(
+ | stage => "resolver",
+ | method => "resolve",
+ | args => { host => "" },
+ | on_success => \&handle_address,
+ | on_failure => \&handle_error,
+ | on_timeout => \&handle_timeout,
+ |);
+ Bleh.
+Request Roles Are Shorthand
+ Replace on_foo parameters in a request.
+ |my $req_subrequest = POE::Request->new(
+ | stage => "resolver",
+ | method => "resolve",
+ | args => { host => "" },
+ | role => "dnslookup",
+ |);
+ And it scales, too.
+Role-Based Response Dispatch
+ Methods matching "on_" . $role . "_" . $response_type are called.
+ sub on_dnslookup_success { ... }
+ sub on_dnslookup_failure { ... }
+ sub on_dnslookup_timeout { ... }
+ TODO: on_dnslookup_autoload { ... }
+ Handler attribute implied by "on_" so not needed.
+Now About POE::Stage
+ Standard base class for POE::Stage
+ Implements about 75% of the magic
+ (Rest is in POE::Request)
+POE::Stage Standard Methods
+ new() implemented by the base class
+ on_init() initialization callback during new()
+ Tried to keep it light, so the rest can be yours.
+POE::Stage Exported Functions
+ Oh, some more pollution.
+ self() accessor to $self. self->method()
+ req() inbound request accessor: req->return(...)
+ rsp() inbound response accessor: rsp->recall(...)
+ expose() seen before
+ Ok, really, that's it.
+ So far.
+ We'll try to be good.
+Standard POE::Stage Classes
+ App - The top-level application.
+ The rest have unstable interfaces.
+ We could use your help here.
+What About POE?
+ POE::Stage uses POE for lower-level services.
+ POE::Watcher classes are OO versions of POE features.
+ Design still in flux.
+ We could use your help here, too.
+POE::Watcher Classes
+ OO versions of POE things.
+ Follow Perl GC rules, not POE's.
+ Cancel by destroying the object.
+ Store in $req_ to auto-cancel if parent request finalized.
+ OO version of POE::Kernel->delay() family.
+ |my $req_timeout = POE::Watcher::Delay->new(
+ | seconds => 10,
+ | on_success => "handle_timeout",
+ | args => \%handle_timeout_parameters,
+ |);
+ OO version of POE::Kernel->select_read().
+ |my $req_input = POE::Watcher::Input->new(
+ | handle => $io_handle,
+ | on_input => "read_from_handle",
+ | args => \%passed_along,
+ |);
+ Encapsulates POE::Wheel classes.
+ |my $req_wheel = POE::Watcher::Wheel->new(
+ | wheel_class => "POE::Wheel::Run",
+ | wheel_parameters => {
+ | ...,
+ | StdoutMethod => "handle_child_stdout",
+ | }
+ |);
+ Wheel's "Event" parameters become "Method" in POE::Stage.
+Why Doing This
+ TIMTOWTDI didn't scale.
+ Everybody did something different.
+ Interoperability suffered.
+Why Doing This
+ Design Patterns Aren't.
+ A lot of repeated work became apparent.
+ It's time to subsume them.
+Why Doing This
+ Separate project for fun.
+ Backward compatability not an issue.
+ Can use modern Perl.
+Why Doing This
+ Can involve community earlier in the development process.
+ More chance to avoid strange names for things. :)
+What You Can Do
+ Need peaple to push the design.
+ Core concepts done, barring insurmountable design problems.
+ Catch problems before things go too far.
+What You Can Do
+ Help keep things sane.
+ Single mad scientest model produces monsters.
+ Multiple mad scientists can check and balance.
+ Or at least brainstorm over insurmountable design problems.
+What You Can Do
+ Develop standard libraries.
+ Or at least guide their development.
+ It's easier to get features designed in early than wedged in later.
+What You Can Do
+ Sieze a need and run with it.
+ Unless that need is scissors.
+ Unless they're blunt.
+ Thank you.
577 patterns.otl
@@ -0,0 +1,577 @@
+Patterns of Object Interaction
+ Abstract
+ A useful object framework must support all possible design and interaction patterns.
+ The framework must support a core suite of general-purpose design patterns.
+ The framework must provide a good foundation for external implementation of additional patterns.
+ Top-down design is impossible.
+ An object framework must support all future uses, but it cannot anticipate them.
+ People write programs, and people are unpredictable.
+ Bottom-up design tends to fail.
+ Simple conceptual models work well at small scales.
+ Growing complex systems from basic principles is difficult.
+ There is an early, seductive sense of success.
+ Simple conceptual models often fail over time.
+ Larger systems strain the requirements of simple conceptual models.
+ Prevailing best practices change over time, and new practices introduce new requirements.
+ The rules and corollaries eventually conflict.
+ It's impossible to anticipate everything.
+ A hybrid approach may succeed where the other two fail.
+ It's easier to catalog meta design and interaction patterns than use cases.
+ By cataloging basic object design and interaction patterns, certain basic requirements will emerge.
+ By satisfying these requirements, the emergent object framework will conceptually scale farther.
+ Roadmap
+ Catalog and consider as many design and interaction patterns as possible.
+ Describe the emergent meta patterns.
+ Develop and document a syntax and specification to support the meta patterns.
+ Implement the specification.
+ Call for Contribution
+ Please help.
+ This is a huge project.
+ The project leader has worked on bottom-up designs since 1998 and would like to get it right this time.
+Object Structural Patterns
+ Code Conventions
+ Functions
+ Methods
+ Class Methods
+ Object Methods
+ Parameter Conventions
+ Self and Positional Parameter List
+ Self and Parameter Hashref
+ Lexical Aliases
+ Self
+ Hashref Members
+ Return Conventions
+ Returned Data Formats
+ Returned as a List
+ Returned as a Hashref
+ Type and Hashref
+ Returned Data Mechanisms
+ Return via Return Builtin
+ Emitting via Method
+ Synchronous Emit
+ The emitted message target is called during emit().
+ Bypassing queue latency is efficient.
+ Deep recursion can occur.
+ Broad recursion cannot occur.
+ Requires deep Perl magic to work across process boundaries.
+ Asynchronous Emit
+ A message representing the emit() call is enqueued for the message target.
+ Queue latency makes this slower than synchronous emit.
+ Deep recursion cannot occur.
+ Broad recursion can occur.
+ May work locally or remotely.
+ Hybrid Emit
+ Synchronous emit is used whenever possible.
+ Asynchronous emit is used at the first sign of recursion.
+ Asynchronous emit may also be used for remote messages.
+ Deep recursion cannot occur.
+ Broad recursion is less likely.
+ Constructor Conventions
+ Direct Instantiation
+ Instantiate in Another Thread
+ Instantiate in Another Process
+ Process Already Exists
+ Process Doesn't Exist
+ Instantiation upon Request
+ Destructor Conventions
+ Destruction upon Release
+ Owner Explicitly Releases Object
+ Cascaded Owner Destruction
+ Global Destruction
+ Destruction upon Request
+ External Shutdown Request
+ Avoid Shutdown upon Destruction
+ Shutdown upon destruction tends to be too late.
+ Shutdown may take time.
+ Objects in the throes of destruction don't have time.
+ Self-Destruction upon Task Completion
+ Relies upon weak references or implicit management.
+ May be thwarted by users holding onto additional object references.
+ Accidentally, causing memory leaks.
+ Explicitly, but power users.
+ Object Never Destructs
+ Do nothing vital within object destructors.
+ Object destructor invocation is not guaranteed.
+ POSIX::_exit()
+ Signals.
+Object Composition Patterns
+ Static Class Composition
+ Inheritance
+ Interfaces and Implementations
+ Roles
+ Object Composition
+ Static Object Composition
+ Low-level objects that comprise a higher-level object are created along with the high-level object.
+ The instantiation-time configuration persists until destruction.
+ Dynamic Object Composition
+ A higher-level object creates and by default owns lower-level objects as needed.
+ The type and ordinality of lower-level objects may change over time.
+ Object Composition Roles
+ Lower-level objects fulfill roles within their higher-level objects.
+ Higher-level objects may assign role names to lower-level objects to simplify addressing and management.
+ Role Ordinalities
+ No Objects per Role
+ All objects for a role may have destructed, or no objects for a role may have been constructed yet.
+ One Object per Role
+ Each lower-level object comprising a higher-level object may have its own role, or no role at all.
+ Multiple Objects per Role
+ Multiple objects may be assigned the same role within a higher-level object.
+ Role Addressing
+ Addressing All Objects for a Role
+ Addressing One Object for a Role
+ Addressing One Object at Random
+ Round-Robin Addressing
+ Custom Addressing
+ Owner Ordinalities
+ No Owners
+ An object without an owner is usually a memory leak as a side oeffect of a circular reference.
+ If at all possible, objects should recognize and log a warning when they have been orphaned.
+ If possible, objects should recognize and throw excpetions when too many are leaking.
+ One Owner at a Time
+ Creator
+ An object's scope remains that of its creator for the object's lifetime.
+ Factory
+ One object creates new objects on behalf of another.
+ Namespace
+ An object is created within an object that allows it to be addressed by name.
+ An object is created outside a namespace and is later registered with the namespace.
+ Assembly Line
+ An object is created to represent some multi-stage task.
+ The object is passed from one worker to another.
+ Each worker performs part of a larger complex task.
+ The object represents a complete result when all stages are complete.
+ Multiple Owners
+ An object is created by one object and passed to one or more others.
+ Multiple Serial Owners
+ Each owner relinquishes ownership while passing the object to the next.
+ Multiple Parallel Owners
+ An object is created by one object and passed to one or more simultaneous users.
+ Use must be coordinated from within the object being used.
+ Users are not aware of each other.
+ Owned Ordinalities
+ Owns No Objects
+ Owns One or More Objects
+ Explicit Ownership
+ This is Perl's standard ownership mechanism.
+ Objects are stored in members of their owners.
+ Objects are destroyed when their owners release them.
+ Implicit Ownership
+ About
+ The base class tracks object ownership and parentage.
+ Dynamic composition is simplified.
+ Objects are permitted to self-destruct when they are finished.
+ Objects are identified by their roles within their owners.
+ The mechanism may be visualized as object-scoped namespaces.
+ Implicit Ownership upon Creation
+ Objects are assigned roles at construction time.
+ The base class tracks owned objects by roles.
+ Implicit Ownership upon Request
+ Objects created without roles may be assigned roles later.
+ The base class begins tracking these objects at the time of assignment.
+ Unassinging roles may trigger destruction if the base class held the sole reference to these objects.
+ Inspecting Implicitly Owned Objects
+ Addressing Owned Objects
+ Addressing owned objects by Role
+ Addressing Owned Objects by Class
+ Addressing a Single Owned Object
+ Addressing Multiple Owned Objects
+ Iterating Owned Objects
+ Iterating owned objects by Role
+ Iterating owned objects by Class
+ Counting Owned Objects
+ Counting Owned Objects by Role
+ Counting Owned Objects by Class
+ Benefits of Ownership
+ Default response target.
+ Role and type responses.
+ Transferring Ownership
+ Implicitly during storage.
+ This is Perl's referencing model.
+ Storing an object also implies sets ownership.
+ Releasing an object relinquishes ownership.
+ Easy to implement---just let Perl do it.
+ Difficult to convey benefits without ability to introspect owner relationships.
+ Explicitly via method.
+ Explicit mechanisms are easier to understand.
+ More work for users.
+ More reliable---no need for Perl magic.
+ Determining Ownership in Perl
+ Examine the call stack via caller() in package DB.
+ Have the framework call everything, all the time.
+ Decorator that injects the current $self.
+ Nick Perez suggested this.
+ Custom decorators can be defined with Devel::Declare and MooseX::Declare.
+ A simple C<< parent SomeObject->new() >> might deliver the necessary information.
+ It's a little magicky, but it might be easier (and saner) than walking the call stack.
+ MRO::Magic
+ Nick Perez suggested this.
+ Rjbs is working on it.
+ It's not necessary to track all object ownership.
+ Basic objects that don't use the framework don't need to be tracked.
+ Service Composition
+ Service Scope
+ Available to One Object
+ Generally pointless, since services are meant to be visible in wider scopes.
+ Available to Multiple Objects
+ It is ideal for a service to be available and useful for multiple objects.
+ The service must coordinate requests internally.
+ Objects cannot coordinate use of a service.
+ This is common, so it must be part of a base service class.
+ Available to No Objects
+ Invisiblity is useless.
+ A service must be visible to be used.
+ Service Ownership
+ A serice is owned by a single entity that exposes it to other objects.
+ Other objects may not assume ownership of a service.
+ Service Exposure
+ Service Exposed Within One Process
+ Service Exposed Internally and to Other Processes
+ Service Exposed Only to Other Processes
+ Service Creation
+ Service Creation by Configuration
+ Service Creation upon Request
+ Service Creation Implicitly upon Need
+ Service Destruction
+ Service Destruction upon Request
+ Graceful Shutdown
+ Immediate Shutdown
+ Service Destruction upon Container Destruction
+ Global Destruction at Program Exit
+Object Interaction Patterns
+ Synchronous
+ Call and Return
+ Request and Wait for Reply
+ Ordinalities
+ One Call and One Request
+ Asynchronous
+ Request and Asynchronous Callback
+ Callback by Function Reference
+ Supports continuations.
+ Supports quick, low-level code.
+ Callback by Object or Class and Method Name
+ Callback by Role and Response Type
+ Promises
+ Requests as Promise Factories
+ Waiting for Promises
+ Request Ordinalities
+ No Requests
+ One Request
+ Multiple Requests
+ Response Ordinalities
+ No Responses
+ One Response
+ Multiple Responses
+Task Patterns
+ Task Lifespam
+ Task Commencement
+ Task Begins with Object Instantiation
+ Task Begins upon Request Receipt
+ Task Completion
+ Task Ends upon Successful Completion
+ Task Ends upon Exception
+ Task Ends with Cancellation Request
+ Task Ends with Object Shutdown
+ Task Ends with Object Destruction
+ Objects may be destroyed before they are finished.
+ Global destruction is an extreme case.
+ There may be a race between the task completion and object destruction.
+ A user may knowingly cancel a task by destroying the object performing it.
+ Task Never Ends
+ Programs may halt without notification or opportunity to clean up.
+ There's nothing to be done in these cases.
+ If absolute reliability is required, try to minimize the amount of time when sudden halting can be catastrophic.
+ Task Ordinality
+ No Tasks Per Object
+ An object may be created for a purpose that is not needed in a partucular execution.
+ Optimally, the object would not be created until its task is required.
+ One Task Per Object
+ Multiple Tasks Per Object
+ Tasks Performed Serially
+ Tasks Performed in Limited Parallelism
+ Tasks Performed without Parallelism Limit
+Communication Patterns
+ Terms
+ Producer
+ An object that produces information.
+ Also known as a source.
+ Might be a better name than "responder".
+ POE::Wheel is a kind of producer.
+ POE::Component::IRC is both a producer and a consumer.
+ Consumer
+ An object that consumes information from a producer.
+ Also known as a sink.
+ Objects may be both producers and consumers at the same time.
+ Requester
+ An object that initiates a transaction by making a request.
+ Requests may be performed by sending messages to services.
+ Some objects imply requests when they are created.
+ Method calls are a form of request.
+ Requesters produce requests.
+ Requesters may consume responses.
+ Responder
+ An object that receives a request and performs some kind of work.
+ Called responders because they often respond to requests.
+ Some objects perform side effects without responding.
+ A universal sink (the /dev/null of objects) may neither respond nor perform a side effect.
+ Consider calling them workers.
+ Responders may consume requests.
+ Responders may produce responses.
+ To Do
+ The producer/consumer and requester/responder combinations may need to be enumerated and explained in more detail.
+ Discrete Transactions
+ Ordinalities
+ Point to Point
+ One Requester, One Responder
+ Broadcast and Gather
+ One Requester, Any Responders
+ Serial Responders
+ Parallel Responders
+ Message Channels
+ Any Requesters, Any Responders
+ Service
+ Any Requesters, One Responder
+ Multi-Transaction Sessions
+ Ordinalities
+ Point to Point
+ One Connector, One Service
+ Observation and Notification
+ Terms
+ Notifier
+ An object that advertises notifications when its data members change.
+ Observer
+ An object that observes data member changes in one or more other objects.
+ An object may observe its own data members.
+ Ordinalities
+ No Notifiers, Any Observers
+ Ideally the system will optimize this case into a no-op.
+ Runtime support for dynamic ordinalities may prevent optimization.
+ Any Notifiers, No Observers
+ Ideally the system will optimize this case into a no-op.
+ Runtime support for dynamic ordinalities may prevent optimization.
+ One Notifier, One or More Observers
+ Notofication is sent to all observers.
+ One or More Notifiers, One Observer
+ An observer may observe more than one notifier.
+ It remains to be seen whether this case is practical.
+ Multiple Notifiers, Multiple Observers
+ The observation/notification equivalent of a data bus.
+ It also remains to be seen wheter this is practical.
+ Notifications
+ Notification on Set
+ Observers are notified whenever a value is written to an observed member.
+ Obseration occurs even when the new value is identical to the old one.
+ Level-triggered notification.
+ Notification on Change
+ Observers are notified whenever a new value is written to an observed member.
+ Obseration does not occur when the new value is identical to the old one.
+ Edge-triggered notification.
+Continuation Patterns
+ About
+ Continuations are encapsulated bits of program state that can be passed around and swapped in and out as needed.
+ Each continuation includes an instruction pointer and all the program state required to resume a program from that point in its execution.
+ Perl supports coroutines by grafting its interpreter onto an event dispatcher.
+ This grafting is done deep in its implementation using sharp implements.
+ Continuations may also be implemented as explicit objects to manage execution state between callbacks.
+ Event frameworks like POE implement such coroutines, albeit at a rather low level.
+ Multiple continuations may be active at once.
+ Continuations may be nested, in which case the inner continuation should run to completion before the outer one may resume.
+ Lexical::Persistence
+ Lexical::Persistence was written to map continuation object data members into lexical pads.
+ This simplifes their use---lexical variables magically refer to the right continuation.
+ It's somewhat off-putting magic, however.
+ Perl seems to behave abnormally.
+ An alternative, explicit mechanism might feel nicer.
+ Request Based Continuations
+ About
+ Tasks require their own continuations.
+ Each task is initiated by some form of request.
+ The request may be implicit in an object's creation.
+ It may be an explicit message sent to a service.
+ Inbound Request Continuations
+ Inbound request continuations are state associated with tasks that one object or service performs on behalf of another.
+ These continuations are associated with inbound requests.
+ They are accessible within receivers of requests.
+ They are automatically made available whenever code is executed as a consequence of the initial request.
+ In other words, these continuations are in scope during the performance of a task triggered by some request.
+ Outbound Request Continuations
+ Outbout request continuations associated with tasks that are being performed by another object upon the current object's request.
+ These continuations are associated with outbound requests.
+ They are accessible within request senders, or method callers.
+ They are automatically made available whenever a response is received by the helper object or service.
+ These continuations provide continuity between asynchronous messages and the responses they generate.
+ Object Based Continuations
+ Self Continuations
+ Each object has a continuation that is in scope whenever the object is active.
+ This continuation is the object itself.
+ Parent Object Continuations
+ These continuations are special cases of Inbound Request Continuations.
+ They exist when the parent object created the current object for the purpose of performing a task.
+ Are there other useful uses of parent object continuations?
+ Child Object Continuations
+ These continuations are special cases of Outbound Request Continuations.
+ They exist when the parent object created the current object for the purpose of performing a task.
+ Are there other useful uses of parent object continuations?
+ Connection Based Continuations
+ About
+ Persistent connections or sessions between objects are useful.
+ Continuation scope and lifetime can be associated to persistent connections.
+ Management of connection state is automated as a result.
+ Connector's Continuation
+ Connector continuations are associated with the client sides of connections between objects.
+ They provide continuity over the course of the connection.
+ Additionally, outbound request continuations may be associated with individual requests that are sent down connections.
+ Service's Continuation
+ Service continuations are associated with the server sides of connections between objects.
+ They provide continuity within the service over the course of the connection.
+ Additionally, inbound request continuations may be associated with individual requests that a service may receive.
+ Lexical Aliases for Continuation Variables
+ About
+ Lexical::Persistence was written to provide easy lexical aliases for continuation variables.
+ Members of a continuation object may be aliased to lexical variables within a callback.
+ Accessing or modifying lexical variables magically does the same to members of the continuation object.
+ However, the aliasing incurs overhead and is not lazy.
+ All aliases are configured regardless whether a particular code path requires them.
+ Lexical Alias Conflicts
+ Multiple continuations may be active at once.
+ They may have identical data members.
+ Lexical variable names need to identify the continuations to which they refer.
+ POE::Stage and Lexical::Persistence use prefixes to disambiguate continuations.
+ The part of the variable name up to the first underscore identifies the continuation.
+ The remaining variable name identifies the data member within the named continuation.
+ Additional Conveniences
+ $self may automatically be aliased to $_[0], Perl's conventional method parameter identifying the object.
+ The "self" prefix may be aliased to members of $self.
+ $args may be aliased to a hashref of method parameters, possibly kept in $_[1].
+ Likewise, the "arg" prefix may be aliased to $args members.
+Miscellaneous Ideas
+ Metaphors
+ Extending the Actor Metaphor
+ Actor
+ An object that can take requests and respond with results.
+ Described as "services" elsewhere.
+ May also be helper objects.
+ POE::Session is a kind of actor, although not in the computer science sense of the word.
+ POE::Wheel objects aren't actors because they don't stand alone.
+ In this metaphor, actors don't include their own mailboxes, nor do they actively await messages.
+ Prop
+ Basic, non-actor helper objects.
+ They may interact with messages, or use basic asynchronous callback facilities like timers.
+ They generally perform very low-level work.
+ Actors use them to fulfill their roles.
+ Director
+ The event loop, message router and dispatcher.
+ May represent POE::Kernel within the metaphor.
+ Stage
+ About
+ Isolated computational units.
+ More like conventional actors.
+ Ideally, stages should behave identically no matter what.
+ In practice, each type of stage probably has its own caveats.
+ Cooperative Stages
+ Act as thin interfaces between POE::Kernel and actors.
+ Don't have their their own mailboxes.
+ Immediately and synchronously forward events to actors.
+ Threaded Stages
+ Act as bidirectional queues between POE::Kernel (which lives in the main thread) and the actors that coexist within a subthread.
+ Contain their own mailboxes.
+ Cannot directly call anything that exists in another stage.
+ Other iThreads caveats apply.
+ Forked Stages
+ Act as bidirectional queues between POE::Kernel (which lives in the main process) and the actors that coexist within a child process.
+ Contain their own mailboxes.
+ Cannot directly call anything that exists in another stage.
+ Other process-boundary caveats apply.
+ Propmaster
+ An ORM of some sort.
+ DOM Namespaces
+ XPath Object Addressing
+ About
+ Allows global addressing of objects through a DOM-like container and XPath-like queries.
+ Proof of concept exists using XML::LibXML and actual DOM and XPath queries.
+ Supports multiple-object addressing.
+ Supports identifying objects by class, role, and other attributes.
+ In a cluster, nodes may advertise their services by adding their DOMs to a directory.
+ The directory can execute XPath queries that span the entire network.
+ Caveats with XPath Object Addressing
+ Robert Grimes pointed out that there is very little actual need for finding objects globally.
+ Most objects interact locally.
+ Parent object interacts with children.
+ Children interact with parents.
+ Children interact with siblings, usually through a moderator.
+ Global addressing facilitates broken encapsulation.
+ Global addressing should only be used for services.
+ Javascript use of DOM Addressing
+ Torsten Raudssus pointed out that Javascript uses DOM for similar purposes.
+ Code may manipulate page elements gingly or in groups by addressing them with XPath.
+ It can be very convenient.
+ This seems to be a subset of Robert Grimes' earlier point.
+ Javascript is manipulating sibling objects within the same container---the page containing the code.
+ In a larger application, it seems safer to limit each object's reach.
+ What sorts of limitations are reasonable?
+ Proxy Objects
+ About
+ Proxy objects are an alternative to services and explicit messages.
+ Remote Object Type
+ Remote Helper
+ Remote Service
+ Remote Object Existence
+ Remote Object Already Exists
+ The local proxy object connects to the remote object during instantiation or first use.
+ Remote Object Created on Demand
+ Creating the local proxy triggers creation of the corresponding remote object.
+ Remote Process Existence
+ Remote Process Already Exists
+ The local proxy object connects to the remote process during instantiation or first use.
+ Remote Process Created on Demand
+ Remote processes are created as needed.
+ Remote Class Existence
+ Remote Process Has Required Class
+ Remote objects are instantiated from remote copies of the requied class.
+ Incompatible versions of the same class may cause problems.
+ Remote Process Needs Required Class
+ The local process may push a required class to the remote process.
+ Dependencies may also need to be pushed.
+ In some cases, tarballing the entire module suite may be needed.
+ The remote process must have a version of Perl capable of executing the remote object.
+ Injecting code into other processes or even other machines must be done securely.
+ The remote process should cache the code to avoid additional performance issues.
+ Alternatively, the remote process may install the required module from CPAN.
+ Compiled modules have their own set of problems.
+ Modules may need to be built on the destination machine to guarantee they work.
+ Further Considerations
+ Blocking Constructors
+ Constructors are expected to return complete, usable objects.
+ Remote procedure calls imply blocking until responses are ready.
+ Promises can alleviate this somewhat.
+ Promises are permitted to work in the background until their information is needed.
+ They therefore block less than synchronous calls.
+ However they may still block for significant amounts of time.
+ Conserving TCP Sockets
+ One implementation could use a TCP connection per remote object.
+ TCP connection building and teardown are expensive.
+ It will be more efficient to multiplex object communication between the same processes.
+ The BXXP protocol seems designed for this task.
+ Reflexive Data Members
+ POE's early object environment experiments were very MUD-like.
+ Nearly every object was required to be in a container.
+ Changing an object's container required updates to its old and new containers' contents.
+ This was a fundamental aspect of the system.
+ The system implemented basic code to handle the referential integrity.
+ Procedure
+ Ask the object whether its container may be changed.
+ Ask the old container whether the object may be removed.
+ Ask the new container whether the object may be added.
+ Move the object from its old container to its new container.
+ Notify the old container that the object was removed.
+ Notify the new container that the object was added.
+ Notify the object that its container has changed.
+Technology Questions
+ How are new Moose types defined?
+ New types may be needed for some of the container magic.
+ How may hooks be affixed to Moose members?
+ Attribute traits allow accessors and mutators to behave differently.
+ Member change advertisement may be implemented as traits.
+ Chris Williams suggested Variable::Magic as well.
+ How does Moose map to this framework's features?
+ Moose features seem to be coupled to classes rather than individual objects.
+ How can Moose implement the basic functionality necessary for the features listed in this document?
68 requirements.otl
@@ -0,0 +1,68 @@
+Framework Requirements
+ About
+ This document summarizes the best ideas from the patterns document.
+ The patterns document tries to enumerate all available options.
+ The requirements document chooses which ones to actually use.
+ A later specification document will attempt to reconcile the requirements into a syntax and semantics.
+ Undesirable Qualities
+ Implicitness
+ Implicitness makes learning hard.
+ Invisible action is a mystery for the naive reader.
+ Unnecessary Magic
+ Magic is scary.
+ It also implies action at a distance.
+ Cleverness
+ Cleverness is fun, though. :(
+ Standardize Calling Convention
+ Parameters
+ my ($self, $args) = @_;
+ my $foo = $args->{foo};
+ Return Values
+ Continuations as Super Heaps
+ Continuations scoped and lifetime-tied to resources.
+ Automatic cleanup triggered by resource release.
+ Request-scoped continuations cleaned up on request cancelation.
+ Eliminates manual heap cleanup.
+ See discussions about continuations in patterns.
+ Full Object Orientation
+ Full subclass support.
+ Full composition (has-a) support.
+ Static compile-time support.
+ Dynamic runtime support.
+ Smaller Names
+ POE::Stage instead of POE::Component.
+ Flatten the hierarchy somewhat.
+ All Kinds of Callbacks
+ Coderefs
+ Anonymous
+ Support closures.
+ Support faux CPS.
+ Named subroutine references
+ Support reusable handlers.
+ Methods
+ Class
+ Object
+ Objects Handle Their Own Responses First
+ Objects have the first opportunity to handle their own events.
+ Allows subclasses to handle or alter events on their way out.
+ If unhandled, emitted events bubble up to the object's owner.
+ Typed Return Values
+ Object Roles
+ Role Based Handlers
+ The sender's role and the message type define a potential handler name.
+ Call and Return Semantics for Messages
+ Nested messages complete before outer messages.
+ Simplifies task coordination in a way that most people need.
+ Canceling an outer request triggers the cancelation of inner requests.
+Foundation Classes
+ Watchers
+ I/O
+ Time
+ Signal
+ Suggestions welcome.
+ Stages
+ Application
+ Server
+ Stream
+ Process
+ Suggestions welcome.

0 comments on commit 25da785

Please sign in to comment.