This file is indexed.

/usr/share/perl5/Message/Passing/Role/ConnectionManager.pm is in libmessage-passing-perl 0.116-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package Message::Passing::Role::ConnectionManager;
use Moo::Role;
use MooX::Types::MooseLike::Base qw/ Bool ArrayRef /;
use Scalar::Util qw/ blessed weaken /;
use Carp qw/ confess /;
use Message::Passing::Exception::ConnectionDisconnected;
use Message::Passing::Exception::ConnectionTimeout;
use namespace::clean -except => 'meta';

requires '_build_connection';

sub BUILD {
    my $self = shift;
    $self->connection;
}

with qw/
    Message::Passing::Role::HasTimeoutAndReconnectAfter
    Message::Passing::Role::HasErrorChain
/;

has _timeout_timer => (
    is => 'rw',
);

has connected => (
    is => 'ro',
    isa => Bool,
    default => sub { 0 },
    writer => '_set_connected',
);

has connection => (
    is => 'ro',
    lazy => 1,
    predicate => '_has_connection',
    builder => '_build_connection',
    clearer => '_clear_connection',
);

after _build_connection => sub {
    my $self = shift;
    weaken($self);
    $self->_timeout_timer($self->_build_timeout_timer);
};

sub _build_timeout_timer {
    my $self = shift;
    weaken($self);
    AnyEvent->timer(
        after => $self->timeout,
        cb => sub {
            $self->error->consume(Message::Passing::Exception::ConnectionTimeout->new(
                after => $self->timeout,
            ));
            $self->_timeout_timer(undef);
            $self->_set_connected(0); # Use public API, causing reconnect timer to be built
        },
    );
}

sub _build_reconnect_timer {
    my $self = shift;
    weaken($self);
    AnyEvent->timer(
        after => $self->reconnect_after,
        cb => sub {
#            $self->error->consume("Reconnecting to ...");
            $self->_timeout_timer(undef);
            $self->connection; # Just rebuild the connection object
        },
    );
}

before _clear_connection => sub {
    my $self = shift;
    return unless $self->_has_connection;
    $self->_timeout_timer($self->_build_reconnect_timer);
};

has _connect_subscribers => (
    isa => ArrayRef,
    is => 'ro',
    default => sub { [] },
    writer => '_set_connect_subscribers',
);

sub __clean_subs {
    my $self = shift;
    my $subs = [ grep { weaken($_); defined $_ } @{$self->_connect_subscribers} ];
    $self->_set_connect_subscribers($subs);
}

sub subscribe_to_connect {
    my ($self, $subscriber) = @_;
    confess "Subscriber '$subscriber' is not blessed" unless blessed $subscriber;
    confess "Subscriber '$subscriber' does not have a ->connected method" unless $subscriber->can('connected');
    $self->__clean_subs;
    my $subs = $self->_connect_subscribers;
    push(@$subs, $subscriber);
    if ($self->connected) {
        $subscriber->connected($self->connection);
    }
}

after _set_connected => sub {
    my ($self, $connected) = @_;
    $self->__clean_subs;
    my $method = $connected ? 'connected' : 'disconnected';
    foreach my $sub (@{$self->_connect_subscribers}) {
        $sub->$method($self->connection) if $sub->can($method);
    }
    $self->_timeout_timer(undef) if $connected;
    if (!$connected && $self->_has_connection) {
        $self->error->consume(Message::Passing::Exception::ConnectionDisconnected->new);
        $self->_clear_connection;
    }
};

1;

=head1 NAME

Message::Passing::Role::ConnectionManager - A simple manager for inputs and outputs that need to make network connections.

=head1 DESCRIPTION

This role is for components which make network connections, and need to handle the connection not starting,
timeouts, disconnects etc.

It provides a simple abstraction for multiple other classes to be able to use the same connection manager, and
a notifies

=head1 REQUIRED METHODS

=head2 _build_connection

Build and return the connection we're managing, start the connection
process.

Your connection should use the API as documented below to achieve notification of connect and disconnect events.

=head1 API FOR CONNECTIONS

=head2 _set_connected (1)

Notify clients that the connection is now ready for use.

=head2 _set_connected (0)

Notify clients that the connection is no longer ready for use.

Will cause the connection to be terminated and retried.

=head1 API FOR CLIENTS

To use a connection manager, you should register yourself like this:

    $manager->subscribe_to_connect($self);

The manager will call C<< $self->connected($connection) >> and C<< $self->disconnected() >> when appropriate.

If the manager is already connected when you subscribe, it will immediately call back into your
C<< connected >> method, if it is not already connected then this will happen at a later point
once the connection is established.

See L<Message::Passing::Role::HasAConnection> for a role to help with dealing with a connection manager.

=head1 ATTRIBUTES

=head2 connected

A Boolean indicating if the connection is currently considered fully connected

=head2 connection

The connection object (if we are connected, or connecting currently) - can
be undefined if we are during a reconnect timeout.

=head2 timeout

Connections will be timed out and aborted after this time if they haven't
successfully connected.

Defaults to 30s

=head2 reconnect_after

The number of seconds to wait before starting a reconnect after a connection has timed out
or been aborted.

Defaults to 2s

=head1 METHODS

=head2 subscribe_to_connect ($subscriber)

This is called by your Input or Output, as C<< $self->connection_manager->subscribe_to_connect($self) >>.

This is done for you by L<Message::Passing::Role::HasAConnection> usually..

This arranges to store a weak reference to your component, allowing the 
connection manager to call the C<< ->connect >>
or C<< ->disconnect >> methods for any components registered when a connection is established or destroyed.

Note that if the connection manager is already connected, it will B<immediately> call the C<< ->connect >> method.

=head1 SPONSORSHIP

This module exists due to the wonderful people at Suretec Systems Ltd.
<http://www.suretecsystems.com/> who sponsored its development for its
VoIP division called SureVoIP <http://www.surevoip.co.uk/> for use with
the SureVoIP API - 
<http://www.surevoip.co.uk/support/wiki/api_documentation>

==head1 AUTHOR, COPYRIGHT AND LICENSE

See L<Message::Passing>.

=cut