POE = Perl Object Environment POE was originally going to be a mud-like environment for handling objects POE implements an event queue, accepting events and dispatching them to watchers two main classes in POE Kernel - the queue, the watch/dispatch loop Session - a POE event is just a list of data including (kernel fields: event name, sending session), (session fields: receiving session, its private data space) watches also include their own fields so do programs --> a lot of stuff here that I had to listen to closely and squint; no notes sessions can be thought of as threads data, events, watches for one session are kept apart from other sessions' (this encapsulation is manners-based not shotgun-based) POE::Kernel knows which session called it sessions can be thought of as "beans" [ed: I know nothing about beans] sessions can act as message-based interfaces you can wrap a normal object with a POE session interface and in fact, POE::Component::SubWrapper does this automatically sessions can be thought of as "Adapters" as in the pattern session classes customize event dispatch POE::NFA -- a state machine if any one session dies, POE dies unless you use POE::Session::Exception ...which is experimental POE::Session::MultiDispatch lets you have multiple handlers per event they all try until one says, "I'm done." ways to write handlers: inline event handlers: give coderefs handling with methods object_states => [ $object => [ qw(methods) ] ] $object's methods are called for named methods object_states => [ $object => { event => 'method' ... } ] $object's methods are called for named methods, but names differ class methods use package_states instead of object_staes package names instead of object references event fields are passed as @_ instead of worrying about indices, use constants $_[HEAP] for example $_[ARG0] is the start of stuff you pass in $kernel->yield(EVENT, @args); # enqueue event, let everything have time first $kernel->post(SESSION, EVENT, @arg) # enqueue event for other session SESSION is semi-magical and can be a ref, a stringified ref, a sesion ID, or an alias $kernel->call(SESSION, EVENT, @arg); # call an event directly, ignoring queue sessions stop when they have no work to do (_stop event) events count as work so do most event watches aliases allow programs to address sessions by name they can only refer to one session but one session can have multiple names only count as work when something can send events to them a session is the parent of the sessions it creates POE::Kernel is the default parent (like how unix processes default to being children of init) children are work, so parents always outlive their children [ed: how sad!] _parent tells a session that it's being moved ARG0: old parent ARG1: new parent _child tells you that you have a child coming in or going away this is NOT related to SIGCHLD remember: unix processes are not POE sessions timers two ways to watch time absolute timers (alarms) relative tiemrs (delays) two ways to track timers track them by name or by unique id I/O watchers select-like is there input or output waiting? watchers make files binmode and unbuffered watchers do not /perform/ IO they just watch for it hence the name signals signal handlers handle internal signals. (surprise!) rocco hates signal dispatch; the internals are complicated which means the externals are simple! signals sent to a session are also dispatched to its children if any session handles a signal, it's considered handled for the whole tree ? if nothing handles it, the whole tree is killed off signalling POE::Kernel signals the entire program kernel shutdown the kernel runs until all sessions stop sends sigidle if only idle aliased sessions remain wheels objects that encapsulate common watcher and handler paterns wheels are not managed by POE they create and destroy watchers and handlers filters translate data format for wheels don't understand high-level protocols; they're unidirectional for example, POE::Filter::Line takes input and breaks it up on lines takes output and adds newline(s) drivers perform file I/O there's only one that's ever been needed: POE::Driver::SysRW so it's the default