File Coverage

blib/lib/BusyBird/Main.pm
Criterion Covered Total %
statement 84 89 94.3
branch 23 26 88.4
condition 6 6 100.0
subroutine 21 21 100.0
pod 11 11 100.0
total 145 153 94.7


line stmt bran cond sub pod time code
1             package BusyBird::Main;
2 9     9   216424 use strict;
  9         14  
  9         297  
3 9     9   37 use warnings;
  9         10  
  9         198  
4 9     9   3609 use BusyBird::Timeline;
  9         26  
  9         282  
5 9     9   52 use BusyBird::Watcher::Aggregator;
  9         12  
  9         198  
6 9     9   84 use BusyBird::Log qw(bblog);
  9         13  
  9         373  
7 9     9   38 use BusyBird::Config;
  9         11  
  9         155  
8 9     9   34 use Tie::IxHash;
  9         13  
  9         201  
9 9     9   33 use Carp;
  9         28  
  9         435  
10 9     9   37 use Try::Tiny;
  9         12  
  9         6855  
11              
12             our @CARP_NOT = qw(BusyBird::Timeline BusyBird::Config);
13              
14             sub new {
15 63     63 1 248483 my ($class) = @_;
16 63         466 tie(my %timelines, 'Tie::IxHash');
17 63         1324 my $self = bless {
18             timelines => \%timelines,
19             config => BusyBird::Config->new(type => "global", with_default => 1),
20             }, $class;
21 63         162 return $self;
22             }
23              
24             sub timeline {
25 128     128 1 30757 my ($self, $name) = @_;
26 128         305 my $timeline = $self->get_timeline($name);
27 128 100       913 if(not defined $timeline) {
28 112         235 $timeline = $self->create_timeline($name);
29 112         302 $self->install_timeline($timeline);
30             }
31 128         1496 return $timeline;
32             }
33              
34             sub create_timeline {
35 114     114 1 538 my ($self, $name) = @_;
36 114         299 return BusyBird::Timeline->new(name => $name, storage => $self->get_config("default_status_storage"));
37             }
38              
39             sub get_timeline {
40 676     676 1 1166 my ($self, $name) = @_;
41 676         2745 return $self->{timelines}{$name};
42             }
43              
44             sub get_all_timelines {
45 30     30 1 1426 my ($self) = @_;
46 30         30 return values %{$self->{timelines}};
  30         161  
47             }
48              
49             sub install_timeline {
50 119     119 1 1341 my ($self, $timeline) = @_;
51 119 50       281 if($timeline->name eq "") {
52 0         0 bblog("warn", "Invalid timeline name (it's empty)");
53 0         0 return;
54             }
55 119 100       309 if($timeline->name =~ qr{/}) {
56 10         30 bblog("warn", "Invalid timeline name (it contains /)");
57 10         54 return;
58             }
59 109         385 $self->{timelines}{$timeline->name} = $timeline;
60             }
61              
62             sub uninstall_timeline {
63 6     6 1 71505 my ($self, $name) = @_;
64 6         20 my $timeline = $self->get_timeline($name);
65 6         63 delete $self->{timelines}{$name};
66 6         1182 return $timeline;
67             }
68              
69             sub set_config {
70 76     76 1 454 shift()->{config}->set_config(@_);
71             }
72              
73             sub get_config {
74 574     574 1 4692 shift()->{config}->get_config(@_);
75             }
76              
77             sub get_timeline_config {
78 324     324 1 767 my ($self, $timeline_name, $key) = @_;
79 324         451 my $timeline = $self->get_timeline($timeline_name);
80 324 100       2122 my $timeline_config = defined($timeline) ? $timeline->get_config($key) : undef;
81 324 100       543 return $timeline_config if defined $timeline_config;
82 316         413 return $self->get_config($key);
83             }
84              
85             sub watch_unacked_counts {
86 46     46 1 106891 my ($self, %watch_args) = @_;
87 46         136 my $level = $watch_args{level};
88 46 100       114 $level = 'total' if not defined $level;
89 46         63 my $assumed = $watch_args{assumed};
90 46         56 my $callback = $watch_args{callback};
91 46 100 100     235 if(!defined($assumed) || ref($assumed) ne 'HASH') {
92 5         471 croak 'assumed must be a hash-ref';
93             }
94 41 100 100     157 if(!defined($callback) || ref($callback) ne 'CODE') {
95 5         511 croak "callback must be a code-ref";
96             }
97 36         183 my $watcher = BusyBird::Watcher::Aggregator->new;
98 36         303 foreach my $tl_name (keys %$assumed) {
99 56         168 my $timeline = $self->get_timeline($tl_name);
100 56 100       420 next if not defined $timeline;
101             my $tl_watcher = $timeline->watch_unacked_counts(
102             assumed => {$level => $assumed->{$tl_name}},
103             callback => sub {
104 29     29   44 my ($error, $w, $unacked_counts) = @_;
105 29 50       57 if(defined $error) {
106 0         0 $watcher->cancel();
107 0         0 $callback->("Error from timeline $tl_name: $error", $watcher);
108             }else {
109 29         88 $callback->(undef, $watcher, { $tl_name => $unacked_counts });
110             }
111             }
112 50         398 );
113 50 50       237 if(!$tl_watcher->isa('Async::Selector::Aggregator')) {
114 0         0 confess '$tl_watcher is not a Async::Selector::Aggregator. Something is terribly wrong.';
115             }
116 50         110 $watcher->add($tl_watcher);
117 50 100       1478 last if !$watcher->active;
118             }
119 36 100       185 if(!$watcher->watchers) {
120 4         877 croak "assumed argument does not contain any installed timeline.";
121             }
122 32         231 return $watcher;
123             }
124              
125              
126             1;
127              
128             __END__