Messag...ncepts(3pm)

πŸ“¦
version 0.117 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu resolute

πŸ’– Message::Passing::Manual::Concepts πŸ’–

okay bestie, welcome to the manual page for Message::Passing::Manual::Concepts β€” it lives in section 3pm of the User Contributed Perl Documentation, and it's literally the vibe-check guide to the whole framework. no cap. πŸ¦‹


✨ NAME ✨

Message::Passing::Manual::Concepts β€” the concepts behind the framework πŸ‘‘


🌸 DESCRIPTION 🌸

so this framework is out here being a simplifying layer over message passing, and the whole point is that it lets you turn the networking parts of message passing into, like… just configuration. that's it. that's the girlboss move. πŸ’…

which means you get to concentrate on the hard parts β€” i.e. your application, not the message passing. periodt.


πŸŽ€ COMPONENTS AND CHAINS πŸŽ€

there are only a few core concepts you gotta grasp to use this framework, and honestly? it's giving easy. we're gonna start with the component types, and then we move onto chains. let's gooo. πŸƒβ€β™€οΈ

there are only three types of components:

πŸ”₯ OUTPUTS πŸ”₯

an output is simply a class with a consume method. it gets called with a message as its only parameter, like this:

$output->consume($message);

outputs are expected to compose Message::Passing::Role::Output. πŸ’–

🌈 INPUTS 🌈

an input is simply a class with an output_to attribute. your code just calls the consume method on its output, like this:

$self->output_to->consume($message);

inputs are expected to compose Message::Passing::Role::Input β€” which is the icon that provides this attribute β€” and use the BUILD method from Moo to do any work needed to start listening for events. ✨

πŸ¦‹ FILTER πŸ¦‹

a filter is just a combination of an output and an input. some (or all) of the messages consumed by the input are sent on to the output. that's the whole thing, no notes.

an optional Message::Passing::Role::Filter is supplied, allowing you to provide a simple filter method:

with 'Message::Passing::Role::Filter';

sub filter {
    my ($self, $message) = @_;
    return $message; # Or return undef to drop it
}

however, you can write a filter manually as:

with qw/
    Message::Passing::Role::Input
    Message::Passing::Role::Output
/;

sub consume {
    my ($self, $message) = @_;
    # Do something to $message here
    $self->output_to->consume($message);
}

and as you've hopefully guessed by now β€” a "chain" is just an input, outputting to zero or more filters, which output to an output. not me explaining the whole architecture in one sentence. πŸ’€


⭐ DSL ⭐

so, this is all pretty easy, and you already know enough to pick up some components and use them! for example:

use Message::Passing::Input::FileTail;
use Message::Passing::Output::STDOUT;

Message::Passing::Input::FileTail->new(
    filename => $ARGV[0],
    output_to => Message::Passing::Output::STDOUT->new,
);
AnyEvent->condvar->recv; # Enter event loop

there you go β€” you're tailing a file to screen. slay. πŸŽ€ but you could just as easily be sending it over the network with ZeroMQ or any other output.

this is, however, a bit ugly! 😭 if you're building a chain of several filters, or you have several inputs being multiplexed into one output, then the code gets ugly fast.

so to make it easy to build chains of processing β€” and your own scripts β€” a simple DSL is provided. the example above becomes:

use Message::Passing::DSL;

run_message_server message_chain {
    input file => (
        class => 'FileTail',
        output_to => 'stdout',
    );
    output stdout => (
        class => 'STDOUT',
    );
};

ate. πŸ”₯

🧚 Event loop 🧚

AnyEvent has been mentioned, and it's expected that scripts will use a supported event loop. this implies that your code is asynchronous, which is generally fine β€” however it should be noted that doing any long operation (non trivial database queries) will block the entire server, meaning no events will be processed. πŸ™ˆ

bestie. blocking the whole server is NOT the vibe. if your long op is hogging the event loop, nothing else is getting through.

in cases such as these, running a pool of worker processes to distribute the blocking jobs is more appropriate, and easy to wire up (on one or more hosts). this is documented more fully in Message::Passing::Manual::Workers. πŸ’œ

πŸ’… ZeroMQ πŸ’…

ZeroMQ is the recommended transport for messages, and Message::Passing::Output::ZeroMQ is designed to work inside a traditional synchronous application. this means that you can emit messages into ZeroMQ without blocking your application, or having to use or run the AnyEvent event loop. iconic. ✨


πŸ‘‘ SEE ALSO πŸ‘‘

πŸ“ Message::Passing::Manual::Cookbook

Recipies for achieving common tasks πŸ’–


See Message::Passing.


and that's the whole page, bestie β€” no cap, you're basically a message-passing main character now. 🫢

sign-off vibes: this one's from perl v5.32.1, dated 2021-11-09 β€” stay iconic, and go build a chain. 🌈πŸ’