File Coverage

blib/lib/BusyBird/Main.pm
Criterion Covered Total %
statement 87 92 94.5
branch 23 26 88.4
condition 6 6 100.0
subroutine 22 22 100.0
pod 11 11 100.0
total 149 157 94.9


line stmt bran cond sub pod time code
1             package BusyBird::Main;
2 9     9   216148 use v5.8.0;
  9         28  
  9         463  
3 9     9   67 use strict;
  9         17  
  9         294  
4 9     9   37 use warnings;
  9         14  
  9         243  
5 9     9   4097 use BusyBird::Timeline;
  9         26  
  9         361  
6 9     9   72 use BusyBird::Watcher::Aggregator;
  9         15  
  9         256  
7 9     9   45 use BusyBird::Log qw(bblog);
  9         12  
  9         553  
8 9     9   44 use BusyBird::Config;
  9         21  
  9         277  
9 9     9   43 use Tie::IxHash;
  9         14  
  9         215  
10 9     9   36 use Carp;
  9         15  
  9         506  
11 9     9   51 use Try::Tiny;
  9         12  
  9         8186  
12              
13             our @CARP_NOT = qw(BusyBird::Timeline BusyBird::Config);
14              
15             sub new {
16 63     63 1 280681 my ($class) = @_;
17 63         576 tie(my %timelines, 'Tie::IxHash');
18 63         1398 my $self = bless {
19             timelines => \%timelines,
20             config => BusyBird::Config->new(type => "global", with_default => 1),
21             }, $class;
22 63         181 return $self;
23             }
24              
25             sub timeline {
26 128     128 1 44925 my ($self, $name) = @_;
27 128         342 my $timeline = $self->get_timeline($name);
28 128 100       1189 if(not defined $timeline) {
29 112         330 $timeline = $self->create_timeline($name);
30 112         344 $self->install_timeline($timeline);
31             }
32 128         2184 return $timeline;
33             }
34              
35             sub create_timeline {
36 114     114 1 462 my ($self, $name) = @_;
37 114         319 return BusyBird::Timeline->new(name => $name, storage => $self->get_config("default_status_storage"));
38             }
39              
40             sub get_timeline {
41 675     675 1 1682 my ($self, $name) = @_;
42 675         3925 return $self->{timelines}{$name};
43             }
44              
45             sub get_all_timelines {
46 30     30 1 1554 my ($self) = @_;
47 30         39 return values %{$self->{timelines}};
  30         199  
48             }
49              
50             sub install_timeline {
51 119     119 1 814 my ($self, $timeline) = @_;
52 119 50       293 if($timeline->name eq "") {
53 0         0 bblog("warn", "Invalid timeline name (it's empty)");
54 0         0 return;
55             }
56 119 100       288 if($timeline->name =~ qr{/}) {
57 10         29 bblog("warn", "Invalid timeline name (it contains /)");
58 10         41 return;
59             }
60 109         379 $self->{timelines}{$timeline->name} = $timeline;
61             }
62              
63             sub uninstall_timeline {
64 6     6 1 123071 my ($self, $name) = @_;
65 6         27 my $timeline = $self->get_timeline($name);
66 6         136 delete $self->{timelines}{$name};
67 6         1597 return $timeline;
68             }
69              
70             sub set_config {
71 76     76 1 557 shift()->{config}->set_config(@_);
72             }
73              
74             sub get_config {
75 574     574 1 5544 shift()->{config}->get_config(@_);
76             }
77              
78             sub get_timeline_config {
79 324     324 1 894 my ($self, $timeline_name, $key) = @_;
80 324         601 my $timeline = $self->get_timeline($timeline_name);
81 324 100       2740 my $timeline_config = defined($timeline) ? $timeline->get_config($key) : undef;
82 324 100       583 return $timeline_config if defined $timeline_config;
83 316         630 return $self->get_config($key);
84             }
85              
86             sub watch_unacked_counts {
87 46     46 1 124932 my ($self, %watch_args) = @_;
88 46         97 my $level = $watch_args{level};
89 46 100       129 $level = 'total' if not defined $level;
90 46         70 my $assumed = $watch_args{assumed};
91 46         60 my $callback = $watch_args{callback};
92 46 100 100     271 if(!defined($assumed) || ref($assumed) ne 'HASH') {
93 5         446 croak 'assumed must be a hash-ref';
94             }
95 41 100 100     196 if(!defined($callback) || ref($callback) ne 'CODE') {
96 5         507 croak "callback must be a code-ref";
97             }
98 36         227 my $watcher = BusyBird::Watcher::Aggregator->new;
99 36         438 foreach my $tl_name (keys %$assumed) {
100 55         184 my $timeline = $self->get_timeline($tl_name);
101 55 100       490 next if not defined $timeline;
102             my $tl_watcher = $timeline->watch_unacked_counts(
103             assumed => {$level => $assumed->{$tl_name}},
104             callback => sub {
105 29     29   53 my ($error, $w, $unacked_counts) = @_;
106 29 50       79 if(defined $error) {
107 0         0 $watcher->cancel();
108 0         0 $callback->("Error from timeline $tl_name: $error", $watcher);
109             }else {
110 29         106 $callback->(undef, $watcher, { $tl_name => $unacked_counts });
111             }
112             }
113 49         406 );
114 49 50       262 if(!$tl_watcher->isa('Async::Selector::Aggregator')) {
115 0         0 confess '$tl_watcher is not a Async::Selector::Aggregator. Something is terribly wrong.';
116             }
117 49         118 $watcher->add($tl_watcher);
118 49 100       1655 last if !$watcher->active;
119             }
120 36 100       221 if(!$watcher->watchers) {
121 4         631 croak "assumed argument does not contain any installed timeline.";
122             }
123 32         253 return $watcher;
124             }
125              
126              
127             1;
128              
129             __END__