File Coverage

blib/lib/Flower/Nodes.pm
Criterion Covered Total %
statement 33 80 41.2
branch 1 12 8.3
condition 0 9 0.0
subroutine 9 15 60.0
pod 0 8 0.0
total 43 124 34.6


line stmt bran cond sub pod time code
1             package Flower::Nodes;
2              
3              
4 2     2   2139 use strict;
  2         5  
  2         49  
5 2     2   10 use warnings;
  2         4  
  2         53  
6 2     2   9 use feature qw(say);
  2         4  
  2         137  
7 2     2   10 use Data::UUID;
  2         3  
  2         125  
8 2     2   991 use Flower::Node;
  2         6  
  2         74  
9              
10 2     2   13 use Scalar::Util qw/refaddr/;
  2         4  
  2         99  
11              
12 2     2   8 use Carp qw/confess/;
  2         4  
  2         1691  
13              
14             my $our_uuid = Data::UUID->new->create_str;
15              
16             sub new {
17              
18 2     2 0 779 my $class = shift;
19 2         4 my $self_ip = shift;
20 2         4 my $self_port = shift;
21              
22 2 50       12 confess "called as object method" if ref $class;
23              
24 2         3 my $self = {};
25 2         5 bless $self, __PACKAGE__;
26              
27             # in the beginning we know only about ourself
28 2         288 say
29             "Creating a new set of nodes with first node ip: $self_ip, port $self_port";
30 2         27 my $us = Flower::Node->new(
31             { ip => $self_ip,
32             uuid => $our_uuid,
33             port => $self_port,
34             parent => $self
35             }
36             );
37 2         8 $self->{nodes} = [$us];
38              
39 2         11 return $self;
40             }
41              
42             sub self {
43 3     3 0 155 my $self = shift;
44 3         21 return $self->{nodes}->[0];
45             }
46              
47             sub add {
48 0     0 0   my $self = shift;
49 0           my $node = shift;
50 0           push @{ $self->{nodes} }, $node;
  0            
51 0           return $self;
52             }
53              
54             sub add_if_necessary {
55 0     0 0   my $self = shift;
56 0           my $args = shift;
57 0           my $uuid = $args->{uuid};
58 0           my $port = $args->{port};
59 0           my $ip = $args->{ip};
60              
61 0           foreach ( @{ $self->{nodes} } ) {
  0            
62             return
63 0 0 0       if ( $_->uuid && $uuid && ( $_->uuid eq $uuid ) ); # we know this one
      0        
64             return
65 0 0 0       if ( ( $_->ip eq $ip ) && ( $_->port eq $port ) )
66             ; # this looks like us, do not add
67             }
68 0           my $node = Flower::Node->new(
69             { uuid => $uuid, port => $port, ip => $ip, parent => $self } );
70 0           push @{ $self->{nodes} }, $node;
  0            
71 0           say "$node added";
72 0           return 1;
73             }
74              
75             sub remove {
76 0     0 0   my $self = shift;
77 0           my $node = shift;
78             $self->{nodes} = [
79             map {
80 0 0         if ( refaddr($_) ne refaddr($node) ) {$_}
  0            
81 0           else { () }
82 0           } @{ $self->{nodes} }
  0            
83             ];
84 0           return $self;
85             }
86              
87             sub list {
88 0     0 0   my $self = shift;
89 0           return @{ $self->{nodes} };
  0            
90             }
91              
92             sub nodes_as_hashref {
93 0     0 0   my $self = shift;
94 0           return [ map { { uuid => $_->uuid, ip => $_->ip, port => $_->port } }
95 0           @{ $self->{nodes} } ];
  0            
96             }
97              
98             sub update {
99 0     0 0   my $self = shift;
100              
101 0           foreach my $node ( @{ $self->{nodes} } ) {
  0            
102              
103             # if node has timed out, remove it
104 0 0         if ( $node->has_timed_out ) {
105 0           print "$node - removing after timeout\n";
106 0           $self->remove($node);
107             }
108              
109             # ping it if we need to, to keep it alive
110             else {
111              
112             # tell the node what the 'us' node is, so it can pass that
113             # information on
114 0           $node->ping_if_necessary( $self->nodes_as_hashref );
115             }
116             }
117              
118 0           say "current nodes:";
119 0           foreach my $node ( @{ $self->{nodes} } ) {
  0            
120 0 0         if ( $node->has_files_object ) {
121 0           say " * $node (" . $node->files->count . " files)";
122             }
123             else {
124 0           say " * $node (no files yet)";
125             }
126              
127             }
128              
129             }
130              
131             1;