Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: a5a26bf9a0
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 908 lines (907 sloc) 41.185 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
[_] 40% Framework Requirements
About this Document
This document summarizes the best ideas from the patterns document.
It is also a master TODO list for Reflex.
It's in Vim Outliner Format.
A plain-text outline where tabs indicate indent levels.
Editing is easier using http://sites.google.com/site/vimoutlinerinfo/ ... version 0.3.4 or later.
Suggestions welcome for a concise, plain-text outline format that's widely supported and software-neutral.
Typography
"[_]" is a checkbox denoting an incomplete to-do item.
"[X]" denotes a completed to-do item.
Checkboxes are followed by percentages of completion, including sub-items.
Items without checkboxes---like the one you're currently reading---are just notes.
The docs/patterns.otl document tries to enumerate all available options.
Even ones that have been discarded.
Even ones we'd like to do but may never get around to.
Patterns contains some sexy, interesting, and hard projects.
Volunteers are welcome.
A later specification document will attempt to reconcile the requirements into a syntax and semantics.
This will probably become the documentation. :)
Project Philosophy
Desirable Qualities
Best practices should be encouraged.
Base classes should set precedents for best practices.
The design should encourage continued use of best practices.
Substandard qualities should be possible but gently discouraged.
People like to have options.
People like to exercise those options, whether or not they're good.
It's not the framework's duty to prevent people from doing what they want.
Undesirable Qualities
Avoid implicit constructs.
Implicit constructs cause action without visible indication.
They are disorienting.
They interfere with comprehension.
Avoid unnecessary magic.
Magic is scary.
It also implies action at a distance.
Avoid cleverness.
Cleverness leads to brittle design.
It also leads to unnecessary magic.
It also leads to implicit constructs.
Avoid metaphors.
Metaphors are harmful when writing abstract frameworks.
Metaphors are useful tools for creating systems that mimic real things.
When designed properly, metaphors provide conceptual and contextual information about a framework.
Metaphors are contradictory to abstract design.
Metaphors provide specific conceptual frameworks.
System designs that fit within these frameworks are elegant.
Systems that wish to use other concepts are generally awkward.
Adapters can connect between metaphors, but they should not be needed.
[_] 16% Documentation Requirements
Many "requirements" are really recommended conventions.
For example:
If we require return values to be typed, or ignored.
Obviously we can't force code to do that.
So we document it.
[_] 0% Style guide?
[_] 0% Event naming conventions.
Event names should read well following "on".
On failure.
On success.
[_] 0% "stopped" role for Reflex::Collections?
[_] 0% How to document these interactions?
[_] 0% Command naming conventions.
stop()
[_] 0% Normalize names in Reflex
[_] 0% Helpers
[_] 0% Internals
[_] 0% Traits
[_] 0% Parts and Reified Objects
[_] 50% Reflex::Manual
[_] 50% Nomenclature
[X] 100% Sandbox namespace name.
[X] 100% Reflexive - USING THIS ONE
Same purpose as the -X namespace convention.
Easiest to type... no modifier key (shift).
Reads better.
Sounds better when speaking.
[X] 100% ReflexX - NOT USING
Conventional.
Expected.
Difficult to say: Reflex-ex.
Or difficult to hear: Reflex
Pretty easy to type, though.
[X] 100% Reflex::Ex - NOT USING
It's taxonomically superior, being hierarchical and all.
Aesthetically unappealing, visually, physically and phonetically.
Sounds like you're stuttering.
More difficult to type.
[_] 0% Reflex is a curated namespace.
[_] 0% Define rules for inclusion.
Threshold for usage on CPAN?
Threshold for requests on mailing list?
Other namespaces are fine.
MooseX.
Elsewhere? I don't care.
[X] 100% Namespace Requirements
[X] 100% Choose a short base name for the namespace.
Large class names are unwieldy.
Objects should be under a single top-level namespace.
What single top-level namespace should be used?
Bacon - Basic Asynchronous Cooperative Object Networks?
Reflex <- chosen one
[X] 100% Choose a relatively flat namespace for the framework.
Excessive namespace nesting is unwieldy.
The namespace should be organized.
How should the namespace be organized?
[_] 40% Class and Object Structural Requirements
[X] 100% Support full object orientation.
[X] 100% Support composition of smaller objects into larger ones (has-a).
[X] 100% Support composition through direct inheritance.
[X] 100% Support composition through class roles.
[X] 100% Support composition through runtime watcher roles.
[_] 0% Method parameters should follow a single standard.
[_] 0% Methods should receive only two parameters.
$self - The object being called.
$message - A Message object, or a subclass.
[_] 0% What about out-of-band information, such as other continuations?
Additional parameters?
Standard members of $message?
Lexical magic?
Not in the base.
Maybe as an extension.
[_] 0% Methods should standardize their return semantics.
[_] 0% What are those semantics?
Ignore return values?
emit() as return?
Maybe as an attribute?
[_] 0% Returned messages must be typed.
[_] 0% Function parameters should follow a single standard.
[_] 0% What should that standard be?
[X] 100% Procedural design should be supported.
Some people will prefer procedural design.
[X] Objects are their own condvars.
$object->next() waits for the object to emit a new event.
[X] 100% Wait for a particular event or one of several events.
A lot of time we're just waiting for an object to enter a particular state.
Event order is maintained; intermediate events are discarded.
[_] 0% Determine whether "role" is a confusing name.
Alternatives:
part
Interestingly ambiguous.
Parts as in objects that assemble into other things.
Parts as in roles or duties in the whole.
duty
Uninterestingly unambiguous.
Dreary name.
No longer than role or part.
job
Shortest alternative.
Ambiguous, since "job" may mean a work unit.
Perhaps drearier than duty.
Not: responsibility
Too long.
Res. or resp. are ambiguous abbreviations.
[X] 100% Object Containership Composition Rules
[X] 100% Containership rules are delegated to the objects themselves.
[X] 100% Runtime roles may be assigned as part of the observation, not the sub-object.
[X] 100% Multiple watchers may have the same runtime role.
This is already possible.
Currently roles address watchers.
Multiple watchers for a role requires additional addressing.
Possibly passing the watcher object into the callback.
[X] 100% Implement a _sender parameter supplied by Reflex::Role::Object.
[X] 100% Default handler method names may be derived from roles and message types.
Sender is a DNS resolver.
Sender's role is "resolver".
Sender emits a "success" event.
Container may define an on_resolver_success() method to handle the event.
[X] 100% Methods
[X] 100% Containership methods are defined by Moose traits.
[X] 100% Moose Observer trait implies that the stored object will be observed by the owner.
[X] 100% Moose Emitter trait implies that changing the attribute emits an event to observers.
[X] 100% Moose introspection allows objects to find their contents.
[X] 100% Class Inheritance Rules
[X] 100% Class inheritance rules are delegated to Moose.
[_] 24% Messaging Requirements
[_] 0% Object command interfaces must be methods.
[_] 0% Methods on the objects themselves may pass messages into themselves.
Synchronous method calls are translated into asynchronous messages.
[_] 0% Methods on the objects may trigger activity that emits new events.
Synchronous actions may start or stop messages emitted by an object.
[_] 0% Objects may be interfaces (proxies) that pass messages to other objects.
Objects may act as interfaces to local or remote services.
Synchronous method calls are translated into asynchronous messages.
[_] 0% Local accessors and simple mutators must be synchronous.
Messages for local accessors and mutators is unnecessary overhead.
[_] 0% Maybe make this part of the style guide.
[_] 44% Objects must be permitted to emit messages into their containers.
[_] 0% Message emission is optional, depending on the use case.
[_] 0% Define a use case where message emission is required.
[_] 0% Define a use case where it's not.
[_] 83% Emitted messages are first handled by the object emitting them.
[X] 100% Subclasses may handle messages emitted by base classes.
[X] 100% Subclasses may emit new messages.
[_] 50% Subclasses may emit the same message without re-catching it.
Implies that events bubble out of the object.
Base class emits, and subclasses pass it outward.
[X] 100% Implement as small methods that re-emit events.
Easy to implement.
Tedious, because you have to implement one for every event.
Slow because of the extra method indirection.
[_] 0% Implement some kind of event mapping.
Hard to implement.
Syntactically messy because the mapping must be made explicit.
This could probably be cleaned up later.
Faster since it avoids the indirection.
[_] 50% Emitted messages are next handled by explicit and role-based observers.
[_] 0% Explicit observers.
[X] 100% Role-based observers.
[X] 100% All forms of message handler (callback) must be supported.
[X] 100% Anonymous Coderefs
Anonymous coderefs support closures.
Anonymous coderefs and closures may be used to implement faux continuation passing style.
[X] Simple.
my $t = Reflex::Timer->new( ..., on_event => \&coderef );
[X] Observer.
$object->watch( watched => $object, event => "name", callback => \&coderef );
[X] Traits.
has member => ( traits => ['Reflex::Trait::Observed'] );
[X] 100% Object Methods
Is this not obvious?
[X] Simple.
my $t = Reflex::Timer->new( ..., on_event => rcb_method($watcher, "method_name") );
[X] Observer (array).
my $t = Reflex::Timer->new( ..., on_event => rcb_object($watcher, \@methods) );
[X] Observer (hash).
my $t = Reflex::Timer->new( ..., on_event => rcb_object($watcher, \%methods) );
Traits not supported at this time.
[X] 100% Class Methods
Classes may be used as singletons.
[X] 100% Do we want to support this?
[X] 100% Promises or condvars.
Named Subroutine References
Named message handlers are exportable as reusable interfaces.
Not needed. Roles perform this task.
[_] 0% Messages must be associated with their triggers.
[_] 0% One message may trigger another, inner message.
[_] 0% The inner message must be associated with the outer message.
If object represent tasks, then messages are not needed.
[_] 0% Do objects represent tasks?
[_] 0% Canceling the outer message must trigger cancelation of all associated inner messages.
[_] 0% Generally, all inner messages should complete before an outer message completes.
This emulates asynchronous call/return semantics for messages.
Task coordination is simplified.
[_] 0% Consider Enterprise Integration Patterns
http://www.enterpriseintegrationpatterns.com/toc.html
[_] 0% Determine relevant patterns.
[_] 0% Reconcile competing patterns.
For example, make sure polling and event-driven consumers work together.
Even if one polling consumer is competing with an event-driven consumer.
[_] 0% Specify the roles and classes to implement these patterns.
[_] 0% Implement them.
Integration Styles
Notes
Not as applicable for event processing.
File Transfer
Shared Database
Remote Procedure Invocation
Messaging
Messaging Systems
Message Channel
Message
Pipes and Filters
Message Router
Message Translator
Message Endpoint
Messaging Channels
Point to Point
Publish Subscribe
Datatype Channel
Invalid Message Channel
Dead Letter Channel
Guaranteed Delivery
Channel Adapter
Messaging Bridge
Message Bus
Message Routing
Content Based Router
Message Filter - remove uninteresting messages from a stream
Dynamic Router - routing changes based on input from other entities
Recipient List - route a message to a list of dynamically specified recipeints
Splitter - process a message containing multiple elements, each of which may be processed in a different way
Aggregator - combine the results of individual but related messages so they may be processed as a whole
Resequencer - convert a stream of related but out-of-sequence messages back into the correct order
Composed Message Processor
Maintain overall message flow when processing a message consisting of multiple elements.
Each element may require different processing.
Scatter-Gather
Maintain overall message flow when a message needs to be sent to multiple recipients.
Each recipient may send a reply.
Routing Slip
Route a message consecutively through a series of processing steps.
The sequence of steps is not known at design time.
The sequence may vary for each message.
Process Manager
Route a message through multiple processing steps.
The required steps may not be known at design time.
Steps may not be sequential.
Message Broker
Decouple the destination of a message from the sender.
Maintains central control over the flow of messages.
Message Transformation
Envelope Wrapper
Allows existing systems to participate in a messaging exchange that places specific requirements on the message format.
Examples: Message header fields, encryption.
Content Enricher
Allows communication with another system if the message originator doesn't have all the required data available.
Adds required data to messages, bringing them in compliance with recipients.
Content Filter
Discard uninteresting parts of messages.
Used to pare down large messages when a significantly smaller data set is required.
Claim Check
Cookie based communication.
Reduces data volume of messages without sacrificing information content.
Normalizer
Process messages that are semantically equivalent but arrive in different formats.
Canonical Data Model
Minimize dependencies when integrating applications that use different data formats.
Messaging Endpoints
Messaging Gateway
Encapsulates access to the messaging system from the rest of the application.
Messaging Mapper
Move data between domain objects and the messaging infrastructure while keeping the two independent of each other.
Transactional Client
How can a client control its transactions with the messaging system?
Polling Consumer
Allows an application to consume messages when ready.
Event-Driven Consumer
Allows an application to automatically consume messages as they become available.
Competing Consumers
Allows a messaging client to process multiple messages concurrently.
Each consumer competes for messages from the source.
Message Dispatcher
How can multiple consumers on a single channel coordinate their message processing?
Selective Consumer
How can a message consumer select which messages it wishes to receive?
Durable Subscriber
How can a subscriber avoid missing messages while it's not listening for them?
Idempotent Receiver
How can a message receiver deal with duplicate messages?
Service Activator
How can an application design a service to be invoked both via various messaging technologies and via non-messaging techniques?
System Management
Control Bus
Effectively administer a messaging system distributed across multiple platforms and a wide geographic area.
Detour
Route a message through intermediate steps to perform validation, testing or debugging functions.
Wire Tap
Inspect messages that travel on a point-to-point channel.
Message History
Effectively analyze and debug the flow of messages in a loosely coupled system.
Message Store
Report against message information without disturbing the loosely coupled and transient nature of a messaging system.
Smart Proxy
Track messages on a service that publishes reply messages to the Return Address specified by the requester.
Test Message
What happens if a component is actively processing messages but garbles outgoing messages due to an internal fault?
Channel Purger
Prevents 'left over' messages on a channel from disturbing tests or running systems.
[_] 0% Session Location Rules
[_] 0% Sessions should only be exposed for POE compatibility.
[_] 0% Multiprocessor Concerns
[_] 0% Reflex must support multiple processors with minimal syntax.
[_] 0% Define units of concurrency.
[_] 0% New objects may be started in other processes.
[_] 0% Processes may be forked at session creation time.
Caveat: The new session is executed in isolation.
[_] 0% Processes may be already established and attached to.
[_] 0% Processes may be local to the current machine.
[_] 0% Processes may also be located on other machines.
[_] 0% Ad-hoc remote processes.
Started by ssh, inetd, or other means.
[_] 0% Remote services.
[_] 0% Already running.
[_] 0% Started as needed, and running as long as needed.
[_] 0% New objects may be run in other threads.
[_] 0% Investigate whether we want to support threads directly.
Threads support may be more efficient on Windows.
Perhaps transparently thread/fork depending on $^O.
Or use fork() only, and allow Perl to choose whether to use processes or threads.
[_] 0% Define possible locations for concurrency units.
[_] 0% Local to the current machine.
Fork and exec a thin manager to proxy the object.
The manager instantiates the object in the subprocess.
[_] 0% On a remote machine.
Requires a valid network between machines.
Attach to an existing service on the remote machine.
Create an ad-hoc service on the remote machine.
[_] 0% Normalize as much as possible.
Use services locally to minimize special cases?
[_] 0% Possible RPC transports.
Requirements
Good at any distance. Equally good for localhost and internetworked RPC.
Multi-language convenience.
Ability to support multiple transports.
Concurrently would be "nice to have".
However a single transport of any type would also be nice.
POE::Component::IKC
Fails "multi-language convenience".
[_] 0% ZeroMQ
Chip Salzenberg recommends.
I've had trouble getting the Perl bindings built.
Lack of wide compatibility makes this troublesome.
[_] 0% AMQP
Investigate.
[_] 0% Thrift.
Investigate.
Multicast UDP
Fails "good at any distance".
[_] 0% Consider MDNS for finding objects.
[_] 0% Continuation Rules
[_] 0% Continuations may be associated with objects.
$self is such a continuation.
[_] 0% Object-scoped resources (watchers, etc) should be stored in the object's continuation.
[_] 0% Object destruction triggers associated resource cleanup.
[_] 0% Continuations may be associated with messages.
[_] 0% A message's sender and receiver may have their own continuations associated with the message.
[_] 0% Data stored in the sender's continuation is not visible to the receiver.
[_] 0% Receiver data is not visible to the sender.
[_] 0% Message-scoped resources should be stored in the message's continuation.
[_] 0% Message cancelation triggers associated resource cleanup.
[_] 12% Distributed Messaging
[_] 0% General Tasks
[_] 0% Choose a transport.
[_] 0% ZeroMQ.
I'd like to use this, but it doesn't install on OSX.
[_] 0% XMPP.
Help Nick Perez with his stuff, especially Reflexifying it?
Inspired by http://code.google.com/p/serialxmpp/ ... serial over XMPP.
[_] 0% IRC
Ho ho ho!
[_] 0% Make it pluggable?
Ideally.
Not everyone wants to use the same language.
Introduces complexity.
Need a way to minimize additional overhead.
How much is this an issue?
Already introducing network delays.
[_] 0% Make it multiprotocol?
Ideally.
Not every network is homogenous.
Introduces complexity.
Need a way to minimize additional overhead.
How much is this an issue?
Already introducing network delays.
Use Erlang's?
Other languages support this.
Python: http://erlport.org/
[_] 0% Can we use a Reflex thing in Reflex to ferry under-Reflex messages?
[_] 25% Erlang Inspiration
[_] 0% Process ID / Pid
Mortals might understand Erlang processes to be akin to threads.
Each Erlang process tends to perform a single task.
Reflex's closest relative might be the object.
[_] 0% Pid ! Message
[_] 0% Send a message to a process.
Reflex's closest relative might be asynchronous remote method invocation.
[_] 0% Currently Reflex treats local method invocation as commands.
To extend this, we'd need proxy objects on the local side.
Proxy objects are deceptive---you can't call accessors on them, for instance.
However, Reflex::Trait::EmitsOnChange notifies interested parties when attributes change.
[_] 0% Alternatives.
[_] 0% String-and-parameter based messaging.
More flexible than proxy objects.
The design isn't as clean as proxy objects, however.
[X] 100% Erlang's "receive" BIF (Built In Function).
Erlang's "receive" acts as a blocking message receipt and dispatch table.
It's pretty close to the actor pattern.
Erlang can get away with this because its processes are small and cheap.
[X] 100% Reflex objects already receive messages via callbacks.
[_] 0% Erlang Port Mapper Daemon
Erlang Process Information
http://erlang.org/doc/apps/erts/crash_dump.html#id70963
What things Erlang knows about processes.
http://www.erlang.org/doc/reference_manual/processes.html
Erlang Processes.
Process registration.
Process links.
etc.
Erlang Port Information
http://erlang.org/doc/apps/erts/crash_dump.html#id67172
Kind of sparse information, but it's a lead to more details.
http://www.erlang.org/doc/reference_manual/ports.html
More about ports.
Erlang Process Mapping Daemon
http://erlang.org/doc/apps/erts/erl_dist_protocol.html
Started automatically when Erlang starts a distributed node.
Listens on a standard port.
Speaks a standard protocol.
Erlang BIFs map to epmd activities.
Uses DNS to find remote nodes.
When connecting to a remote pid, one uses name@host.
You at least need to know the remote host.
A bit rigid?
Erlang External Term Format
http://erlang.org/doc/apps/erts/erl_ext_dist.html
Used to serialize Erlang data between nodes.
We could use it---or provide it as an option---to speak directly with Erlang processes.
Interoperability with Other Languages
http://www.erlang.org/doc/tutorial/cnode.html
C Nodes are specifically nodes written in C.
Generically, they're nodes written in other languages.
Perl being one possibility.
Distributed Erlang
http://www.erlang.org/doc/reference_manual/distributed.html
General reference.
Erlang Namespace BIFs (Built In Functions)
register(Name, Pid)
$my_namespace{$name} = $pid;
Can now use $name wherever $pid would be used.
unregister(Name)
delete $my_namespace{$name}
whereis(Name)
return $my_namespace{$name}
registered()
return keys 0%my_namespace
Erlang Remote Process Management BIFs
spawn(Node, Module, Function, Args)
Connect to the remote Node.
Instantiate an object of Module.
Invoke its Function, with Args.
TODO - What does it return?
spawn_link(Node, Module, Function, Args)
Connect to the remote Node.
Instantiate an object of Module.
Invoke its function, with Args.
The linkage implies exception notification.
monitor_node(Node, Flag)
If Flag is true, begin monitoring the node.
Otherwise stop monitoring.
The local node will receive a {nodedown, Node} event if the remote Node ever goes down.
node()
Returns the current Node's name.
nodes()
Returns a list of known Node names.
node(Item)
Returns a Node's name, for a given Pid or Port.
disconnect_node(Nodename)
Disconnects from a remote node.
Erlang Group BIFs
group_leader()
Returns the Pid of the current Node's group leader?
group_leader(Leader, Pid)
Sets the group leader of process Pid to be Leader.
Other Erlang BIFs?
TODO
[_] 71% Common primitive classes must be provided.
[_] 50% Callback Abstractions
[X] 100% Reflex::Callback
[X] 100% Reflex::Callback::CodeRef
[X] 100% Reflex::Callback::Method
[X] 100% Reflex::Callback::Promise
[_] 0% Reflex::Callbacks
Syntactic sugar for callback creation.
[_] 0% Need to make this a declarative thing.
[_] 84% Low-level event watchers.
[X] 100% I/O Watchers
[X] 100% Reflex::Role::Readable
[X] 100% Reflex::Role::Writable
[_] 75% I/O Performers
[X] 100% Roles
[X] 100% Reflex::Role::Reading
[X] 100% Reflex::Role::Writing
[X] 100% Reflex::Role::Streaming
[_] 50% Classes
[X] 100% Reflex::Stream
[_] 0% Integrate Data::Transform
[X] 100% Time Watchers
[X] 100% Roles
[X] 100% Reflex::Role::Timeout
[X] 100% Reflex::Role::Wakeup
[X] 100% Reflex::Role::Interval
[X] 100% Classes
[X] 100% Reflex::Timeout
[X] 100% Reflex::Wakeup
[X] 100% Reflex::Interval
[X] 100% Signals
[X] 100% Roles
[X] 100% Reflex::Role::SigCatcher
[X] 100% Classes
[X] 100% Reflex::Signal
[X] 100% Clients and Servers
[X] 100% Roles
[X] 100% Reflex::Role::Connecting
[X] 100% Reflex::Role::Accepting
[X] 100% Reflex::Role::Recving
[X] 100% Classes
[X] 100% Reflex::Acceptor
[X] 100% Reflex::Connector
[X] 100% Reflex::Client
[X] 100% Reflex::UdpPeer
[_] 66% Pool Management
[X] 100% Reflex::Role::Collectible
[X] 100% Reflex::Collection
Manage a collection of Reflex objects.
Removes objects from itself when they shut down.
Reflex servers can use this to manage client objects.
[X] 100% has_many syntactic sugar for Reflex::Collection.
[_] 0% Worker Pools
Lexicon
(These are intial names I'm throwing out to get discussion started.)
Job.
An object repesenting a unit of work needing to be completed.
Composite Job.
A job comprised of smaller jobs.
Worker.
A resource that can perform tasks to increase the completeness of a job.
A job may not be fully completed without the cooperation of multiple workers.
A job may require multiple passes from a single worker to become fully complete.
Workers from multiple pools may be needed to fully complete a job.
Worker pool.
A group of related workers that share common resources.
Pool Manager.
An object that manages a worker pool's resources.
This object may also consider workers to be resources.
Generic Design
Lifeguard
A program has zero or more lifeguards.
Strawman API
TODO
Release API
TODO
Worker Pool
Each lifeguard configures and manages a single worker pool.
Strawman API
TODO
Release API
TODO
Worker
Each worker pool dynamically manages zero or more workers.
Strawman API
TODO
Release API
TODO
Job
Each worker performs tasks for zero or more jobs.
Strawman API
TODO
Release API
TODO
Agorman Specific Business Requirements
Present for practical ideas; not everything will apply a general, base worker pool.
Loading and Unloading Code
Jobs can be created and dropped into one or more libraries (directories, databases?).
Job functionality can be added, removed and improved at runtime.
Jobs as roles can specialize a generic job class by implementing the guts of the job, e.g. work().
Jobs as classes can consume a generic job role, implementing the interface required by the role.
Jobs as classes can inherit a generic job class and implement the work interface.
Unloaded job code should be removed from memory, if possible.
Job Workflows
Job data should be passable between multiple workers, each worker implementing a step or stage of a larger task.
See the Enterprise Integration Patterns elsewhere in this document. I think some of them may apply. --Rocco
Multiple Configurable, Concurrent Worker Pools
A single WorkerPool instance should be able to run multiple pools at once.
Although it might be more logical to instantiate different pools, each with a different configuration.
In this case, however, it may be desirable for all pools to share some global resource limit.
TODO - What is the purpose of job_types?
Example:
| my $pool = WorkerPool->new(
| max_concurrent_jobs => 1,
| min_concurrent_jobs => 1,
| job_types => [ qw( Job1 Job2 ) ],
| );
Pool/Job Coordination
Worker pools must be able to watch for management events from the jobs they run.
A new job has started.
A job has succeeded; here is an optional result.
A job has updated.
TODO - Updated what?
A job has failed. Here is some error condition.
Workers should be able to manage jobs in the pool.
Operations.
Add new jobs.
Remove jobs.
Find jobs.
Retrieve job counts.
Implies that jobs have access to their pools and other pools.
Generic Worker Pool Concepts
[_] 50% Process Watchers
[_] 0% Reflex::Role::ProcReaper?
I can't find a good reason to write this role.
This seems highly dynamic.
Contributions are welcome.
[X] 100% Reflex::PID
[X] 100% Containership Traits
[X] 100% Reflex::Trait::EmitsOnChange
[X] 100% Initial implementation, with explicit syntax.
[X] 100% Make declarative syntax so we can avoid the icky explicit use of traits.
[X] 100% Reflex::Trait::Observed
[X] 100% Initial implementation, with explicit syntax.
[X] 100% Make declarative syntax so we can avoid the icky explicit use of traits.
[X] 100% POE Interfaces
[X] 100% Wheel wrappers.
[X] 100% Reflex::POE::Wheel
Generic base class for POE::Wheel watchers.
[X] 100% Reflex::POE::Wheel::Run
Specific subclass for proving the concept.
[X] 100% Generic Component shims.
[X] 100% Create a postback analog for components that expect postbacks.
Reflex::POE::Postback
About
Creates a coderef that, when called, posts a message to the object's session, with routing information back to the object.
Postbacks use closures to pass @passthru_params to the callback.
Closures can also handle routing information.
Usage syntax must be identical to Reflex postbacks.
Creation syntax may differ from Reflex postbacks.
Identical creation syntax would be to allow others to create them for us.
However, most eternal postback creators use $_[SENDER]->postback().
$_[SENDER] is the Reflex object's session, not an individual object.
Therefore, components that call $_[SENDER]->postback() will not work.
Therefore, $_[SENDER]->postback() syntax is not needed.
To support identical creation syntax.
$_[SENDER] must be a session that maps directly to a single object.
It could be a dynamically created session for the purpose of interfacing.
Indirection would be heavy.
Consider it for a future revision.
[X] 100% Create an event analog for components that expect events.
About
Many components allow callers to specify return events.
We create a unique, anonymous event that calls a specific object and method upon dispatch.
We can pass this event to components that expect them.
Syntax if anonymous events may be blessed objects
my $event = Reflex::POE::Event->new(...);
$_[KERNEL]->post($event, @callback_params);
Syntax if events may not be blessed
About
Some explicit cleanup must be provided and adhered to.
Rely on object DEMOLISH to automatically clean up for us.
CAVEAT: Components that stringify event names will fail.
Sorry, but they must be blessed for now.
The bless and DEMOLISH tracking is very convenient.
I haven't found a good, reliable way to avoid it.
Dispatch Mechanism
_default
Events that are objects in the Reflex::POE::Event class are invoked to deliver themselves.
[X] 100% Session subscription.
About
A client Reflex object creates the component, to be used as a service.
The client Reflex object registers interest in the service's events.
The service's events are posted to all interested Reflex objects.
POE::Component::IRC will be a good example component.
Syntax
Reflex::POE::Session watcher.
Dispatch Mechanism
Sender Interest
The object creates the component.
The object registers interest in all events from the component.
[X] 100% Components that emit specific events require Wheel-like wrappers.
[X] 100% Is this worth supporting?
No. The Session subscriber can detect any events emitted by the component.
[_] 80% Basic Modules
[X] 100% Reflex::Base
[X] 100% Reflex::Role::Reactive
[_] 0% MooseX::Role::Reactive
[_] 0% Fork git project.
[_] 0% Remove all nonessentials.
[_] 0% Fix up dist.ini.
[_] 0% Rename things.
[X] 100% Reflex::Role
[X] 100% Reflex
[_] 13% Primitive program pieces.
[_] 0% Clean up this branch of the outline.
[_] 0% Reflex::App
[_] 0% Does it offer anything in particular?
[_] 0% Strawman implementation.
[_] 0% Determine API.
[_] 0% Reflex::Cron
[_] 0% Strawman implementation.
[_] 0% Determine API.
See POE::Component::Cron for clues.
Would Chris Fedde like to work on this?
[_] 0% Wait for repeating times.
[_] 25% Reflex::Client::HTTP
[X] 100% Reflex::Connector
[_] 0% Reflex::Connector::Keepalive
[_] 0% Strawman implementation.
[_] 0% Determine API.
[_] 0% Reified version of Reflex::Role::Connector::Keepalive?
[_] 0% Reflex::Resolver
[_] 0% Determine API.
[_] 0% Determine how to make asynchronous.
Forked?
Coro?
Threads?
[_] 0% IPV4
[_] 0% IPv6
[_] 0% Reified version of Reflex::Role::Resolver
[_] 0% Is this a reified version of Reflex::Role::Client::HTTP?
Do we really need to be that dogmatic about roles?
What would a role allow us to do?
[_] 0% Reflex::Conduit
[_] 0% Reified version of Reflex::Role::Proxy
[_] 0% Based on the example proxy.
[_] 0% Between-endpoint flow control?
[_] 0% Generic rate throttling?
[_] 0% Reflex::Process
[_] 0% Strawman implementation.
[_] 0% Determine API.
See POE::Wheel::Run for clues.
[_] 0% Reflex::Tail
[_] 0% Strawman implementation.
[_] 0% Determine API.
See POE::Wheel::FollowTail for clues.
[_] 0% Reified version of Reflex::Role::Tail
[X] 100% Reflex::Collection
[_] 0% What else? Probably a lot!
[_] 25% Optimizations.
[X] 100% Only $kernel->call() when we need to switch sessions.
[_] 0% Do we need call() at all?
[_] 0% Explore IO::Lambda's cheat.
[_] 0% Consolidate POE-specific code out into a single role.
Allows other event loops to be supported directly rather than through POE.
me> Let's say I have a class Mumble that's a generic API for something with platform-specific implementations. I have Mumble::Yay and Mumble::Boo with the bits that the Yay! and Boo! platforms need.
me> I want to use Mumble, and Mumble->putty() to do the putty() thing regardless how the platform needs to putty mumbles.
ether> you want a Mumble factory, that will construct a Yay or a Boo for you depending on your platform
doy> yeah
rafl> for example using Module::Implementation
ether> $obj->isa_ok('Mumble'); $obj->can_ok('putty');
doy> Mumble->new->putty is a lot easier to deal with, generally
PerlJam> sounds like the DBI/DBD dichotomy
doy> well, probably something other than ->new, but you know
ether> new_for_my_platform
ether> but shorter
me> Thank you.
[_] 0% POE::Session singleton
[_] 0% has session_id
[_] 0% sub run_all
[_] 0% sub run_within_session
[_] 0% sub call_gate
[_] 0% Abstract event loop things.
[_] 0% Reflex roles must not emit() messages by default.
Stylistic difference.
Roles are statically composed.
emit() is dynamic composition.
Useless overhead.
Many emitted events will go unhandled.
Finding this out at runtime is slow.
Allow the programmer to choose this overhead, only when it's likely to be necessary.
[_] 0% Remove the default emit()s.
[_] 0% Provide a consumer syntax to concisely specify emit()s at "with" time.
[_] 80% Parameterized role cleanup.
[X] 100% Role units of reactive behavior should not emit() events.
[X] 100% Remove event_parameter() from Reflex::Role.
[X] 100% Remove use of event_parameter() entirely.
[X] 100% Remove event_parameters declarations.
[X] 100% Sort the role parameter declarations.
[X] 100% Remove $ev_ variables.
[X] 100% Roles should not define default public "interface" callbacks.
[X] 100% Roles should require consumers to define cb_* callbacks.
[X] 100% Consumers should define cb_* methods, often in terms of Reflex::Callbacks make_emitter() or make_terminal_emitter().
[X] 100% Remove default $cb_* methods from roles.
[X] 100% Attribute parameters should begin with att_ to avoid confusion with simple value parameters.
[X] 100% Rename the attribute_parameters declarations.
[X] 100% Rename corresponding variables in the parameterized roles.
[X] 100% Rename attribute parameters in the consumers.
[X] 100% Require consumers to define the attributes.
[X] 100% The various parameters automatically add their named things to the list of required methods.
[X] 100% Make sure this plan works.
[X] 100% It doesn't.
The things being required depend on the values of specific parameters.
These values aren't known at role definition time.
They are known at role composition time.
[X] 100% Go back to explicit requires().
[X] 100% Rename references in callback_parameter declarations.
[X] 100% Rename references in method_parameter declarations.
[X] 100% Remove the default methods.
[X] 100% Implement the methods in the consumers.
[X] 100% Remove the methods from the roles.
[X] 100% Test all examples.
[X] 100% eg-02-encoding.pl
[X] 100% eg-04-inheritance.pl
[X] 100% eg-05-composition.pl
[X] 100% eg-06-moose-roles.pl
[X] 100% eg-07-wheel-run.pl
[X] 100% eg-08-watched-trait.pl
[X] 100% eg-11-poco-postback.pl
[X] 100% eg-12-poco-event.pl
[X] 100% eg-13-irc-bot.pl
[X] 100% eg-14-synopsis.pl
[X] 100% eg-15-ipc-run.pl
[X] 100% eg-16-timer-inheritance.pl
[X] 100% eg-17-inheritance-no-moose.pl
[X] 100% eg-18-synopsis-no-moose.pl
[X] 100% eg-30-promise-timer.pl
[X] 100% eg-31-promise-object.pl
[X] 100% eg-32-promise-tiny.pl
[X] 100% eg-33-all-callbacks.pl
[X] 100% eg-34-tcp-server-echo.pl
[X] 100% eg-35-tcp-client.pl
[X] 100% eg-36-tiny-coderefs.pl
[X] 100% eg-37-ping-pong.pl
[X] 100% eg-38-promise-client.pl
[X] 100% eg-39-signals.pl
[X] 100% eg-40-proxy.pl
[X] 100% eg-41-signal-twice.pl
[X] 100% eg-42-reflex-in-poe.pl
[X] 100% eg-50-timeout.pl
[X] 100% eg-51-wakeup.pl
[X] 100% eg-60-collection-promise.pl
[X] 100% test-observer.pl
[_] 0% Revise all documentation.
Philosophy
Boolean role parameters are opportunities for new roles or role subclasses.
Static behaviors should be determined at role consumption time.
Not continually evaluated at runtime.
Runtime behavior toggles are only appropriate when behavior should change at runtime.
Something went wrong with that request. Please try again.