The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

MooX::Async::Console - Attach a console to an async module

SYNOPSIS

my Thing;
use MooX::Async;
with 'MooX::Async::Console';
has _console => is => lazy => builder => sub {
    $_[0]->_launch_console(TCP => address => '127.0.0.1', port => 4242);
};
event cmd_foo => sub {
    my $self = shift;
    my %args = @_;
    say "foo";
    $args{inform}->('this thing is happening');
    $args{then}->done('finished');
};

DESCRIPTION

Attaches some machinery to an object which allows it to start listeners such as on a TCP or unix socket which expose a console interface to the object.

This module is a role which mixes in the "_launch_console" method and implements a "ping" and "quit" command. Another module such as MooX::Async::Console::TCP is responsible for managing the socket and the framing protocol.

BUGS

Certainly.

METHODS

_launch_console($module, [@args]) => $console_instance

Loads MooX::Async::Console::$module and creates a new instance of it (with @args) who's on_command event will invoke commands on $self.

If $module begins with :: it is removed and the remainder used as-is.

$self->_launch_console('My::Console::Socket', argu => 'meant');

At present this distribution includes one socket layer module, MooX::Async::Console::TCP.

An on_command event handler is unconditionally appended to the arguments passed to the console's constructor.

Its interface is desribed in "on_command" in "COMMANDS".

COMMANDS

The command handler will be invoked with the arguments decoded by the socket layer implementation launched by "_launch_console". Usually these will come in the form of key/value pairs but need not. 4 items will be appended to the argument list, which therefore constitute two entries which will be included in the command handlers' args if it treats @_ like a hash.

inform => $subref

A subref the command handler can use to send messages to the connected client. What is suitable for the socket layer to receive is not defined. MooX::Async::Console::TCP can accept 0 or more scalars which it concatenates, so probably at least that.

then => $future

A Future which the command handler can complete or fail with the result of executing the command.

The return value from the command handler is usually ignored.

If a Future is returned from the command then that is what's used to determine when the command has completed instead of "then" which was given to the command handler. The command handler is free then to do with the Future as it wishes; it is no longer used by this module.

sub cmd_generic {
  my $self = shift;
  my %args = @_;
  # If you're not sure about the arguments: my %args = @_[-4..-1];
  # or: my ($then, undef, $inform, undef) = map pop, 1..4;
  ...;
  $args{inform}->(...);
  $args{inform}->(...);
  ...;
  $args{then}->done(...);
}
ping [$nonce]

Respond with pong and <$nonce>, if given. Other arguments are ignored.

quit

Disconnect this client session. Arguments are accepted and ignored.

EVENTS

on_command

Understanding this is not necessary to link a console into your own code, it describes the interface used when implementing one's own socket layer.

The event handler invoked when a client executes a command. The definition of the command and objects for communication between the client and the console-using object are provided in %args:

command

A scalar containing the name of the command to be executed. This will be transformed into the cmd_$command event.

args

An optional arrayref containing the arguments to the command handler.

then

A Future which will be completed when the command handler has finished. This is not the Future which the command handler is invoked with. If the command dies or was not found then this Future will be failed with the exception.

Future->fail($message, console =>
    ex      => $@,   # If the command threw one
    command => $command,
    args    => \%args)

Another Future is created which is passed onto the command itself, if the command returns without dying then "then" is completed with the Future the command handler was given.

The command handler is free to return a different Future to this event handler. If it does so then it is that Future which "then" is completed with. Anything else returned from the command handler is ignored.

inform

An optional subref which the command handler may invoke to respond to the client before execution has completed.

Although inform isn't a required argument its default value is sub { ... } which will die if the command handler attempts to use it.

HISTORY

MooX::Async::Console 0.103
on_command/cmd_* interface
line-based TCP implementation

SEE ALSO

MooX::Async::Console::TCP

AUTHOR

Matthew King <chohag@jtan.com>