thrasherbird.pl: Item disco target config was missing.
[thrasher.git] / perl / lib / Thrasher / Plugin / REPL.pm
blob55c87251309366c2fb29742286d788c7afd54ff0
1 package Thrasher::Plugin::REPL;
2 use strict;
3 use warnings;
5 use Thrasher::EventLoop;
6 use Thrasher::Log;
7 use Thrasher::Plugin qw(register_plugin);
9 ### Plugin init
11 # Subclass that integrates itself into a Thrasher::EventLoop.
13 # Warning 1: Anyone who can connect to the REPL port can inject
14 # arbitrary Perl code into the Thrasher process. The only security
15 # measure currently used is binding only to the IPv4 loopback
16 # interface.
18 # Warning 2: A REPL iteration blocks the main loop, so it would be
19 # best to avoid long-lived computations!
20 use base qw(Net::REPL::Server);
22 our $repl_server;
23 sub integrate_repl {
24 my ($component) = @_;
26 $repl_server ||= Thrasher::Plugin::REPL->new(
27 'event_loop' => $component->{'event_loop'},
28 'debug' => 1,
29 'socket_args' => {
30 # path in abstract namespace instead of FS
31 'Local' => "\x00"
32 . '/Thrasher/REPL/' . $component->{'component_name'},
37 register_plugin({
38 'callbacks' => {
39 'main_loop' => { 'Integrate REPL' => \&integrate_repl },
41 });
43 ### REPL::Server callbacks
45 sub debug {
46 my ($self, @words) = @_;
48 if ($self->{'debug'}) {
49 my $line = join(' ', @words);
50 Thrasher::Log::debug($line, $self->{'debug'});
54 sub cb_listen {
55 my ($self) = @_;
57 $self->SUPER::cb_listen();
59 $self->{'event_loop'}->add_fd_watch(
60 $self->{'server'}->fileno(),
61 $Thrasher::EventLoop::IN,
62 sub {
63 $self->interact();
64 return 1;
69 sub cb_connect {
70 my ($self) = @_;
72 $self->SUPER::cb_connect();
74 $self->{'fh_watch_id'} =
75 $self->{'event_loop'}->add_fd_watch(
76 $self->{'fh'}->fileno(),
77 $Thrasher::EventLoop::IN,
78 sub {
79 return $self->interact();
84 sub cb_disconnect {
85 my ($self) = @_;
87 $self->SUPER::cb_disconnect();
89 if ($self->{'fh_watch_id'}) {
90 $self->{'event_loop'}->remove_fd_watch($self->{'fh_watch_id'});
91 $self->{'fh_watch_id'} = undef;