root/trunk/lib/Perlbal/Plugin/EchoService.pm

Revision 774, 3.9 kB (checked in by ask, 17 months ago)

Lots of typo corrections in documentation and comments from Nick Andrew

Line 
1###########################################################################
2# simple plugin demonstrating how to create an add-on service for Perlbal
3# using the plugin infrastructure
4###########################################################################
5
6package Perlbal::Plugin::EchoService;
7
8use strict;
9use warnings;
10
11# on load we need to define the service and any parameters we want
12sub load {
13
14    # define the echo service, which instantiates this type of object
15    Perlbal::Service::add_role(
16            echo => \&Perlbal::Plugin::EchoService::Client::new,
17        );
18
19    # add up custom configuration options that people are allowed to set on the echo_service
20    Perlbal::Service::add_tunable(
21            # allow the following:
22            #    SET myservice.echo_delay = 5
23            # defines how long to wait between getting text and echoing it back
24            echo_delay => {
25                des => "Time in seconds to pause before sending text back using the echo service.",
26                default => 0, # no delay
27                check_role => "echo",
28                check_type => "int",
29            }
30        );
31
32    return 1;
33}
34
35# remove the various things we've hooked into, this is required as a way of
36# being good to the system...
37sub unload {
38    Perlbal::Service::remove_tunable('echo_delay');
39    Perlbal::Service::remove_role('echo');
40    return 1;
41}
42
43
44###########################################################################
45# this is the implementation of the client that gets instantiated by the
46# service.  (which is really all a service does - instantiate the right
47# type of client, and store some information)
48###########################################################################
49
50package Perlbal::Plugin::EchoService::Client;
51use strict;
52use warnings;
53
54use base "Perlbal::Socket";
55use fields ('service', # the service we're from
56            'buf');    # the buffer of what we're reading
57
58# create a new object of this class
59sub new {
60    my $class = "Perlbal::Plugin::EchoService::Client";
61    my ($service, $sock) = @_;
62    my $self = fields::new($class);
63    $self->SUPER::new($sock);
64    $self->{service} = $service;
65    $self->{buf} = "";   # what we've read so far, not forming a complete line
66
67    $self->watch_read(1);
68    return $self;
69}
70
71# called when we are readable - i.e. there is data available
72sub event_read {
73    my Perlbal::Plugin::EchoService::Client $self = shift;
74
75    # try to read in 1k of data, remember to close if you get undef, as that means
76    # something went wrong, or the socket was closed
77    my $bref = $self->read(1024);
78    return $self->close() unless defined $bref;
79    $self->{buf} .= $$bref;
80
81    # now, parse out any lines that we have gotten.  this just removes data line by
82    # line so we can handle it.
83    while ($self->{buf} =~ s/^(.+?)\r?\n//) {
84        my $line = $1;
85
86        # package up a sub to do what we want.  this is in a coderef because we either
87        # need to call it now or schedule it for later.  saves some duplication.
88        my $do_echo = sub { $self->write("$line\r\n"); };
89
90        # if they want a delay, we have to schedule this for later
91        if (my $delay = $self->{service}->{extra_config}->{echo_delay}) {
92            # schedule
93            Danga::Socket->AddTimer($delay, $do_echo);
94
95        } else {
96            # immediately, so run it
97            $do_echo->();
98
99        }
100    }
101}
102
103# called when we are writeable - that is, we are allowed to write data now.  try to
104# flush any existing data and then if we have nothing in the write buffer left,
105# go ahead and stop notifying us about writeability.
106sub event_write {
107    my Perlbal::Plugin::EchoService::Client $self = shift;
108    $self->watch_write(0) if $self->write(undef);
109}
110
111# if we run into some socket error, just close
112sub event_err {
113    my Perlbal::Plugin::EchoService::Client $self = shift;
114    $self->close;
115}
116
117# same thing if we get a hup
118sub event_hup {
119    my Perlbal::Plugin::EchoService::Client $self = shift;
120    $self->close;
121}
122
1231;
Note: See TracBrowser for help on using the browser.