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   221967 use strict;
  9         17  
  9         295  
3 9     9   39 use warnings;
  9         8  
  9         205  
4 9     9   3767 use BusyBird::Timeline;
  9         27  
  9         322  
5 9     9   59 use BusyBird::Watcher::Aggregator;
  9         16  
  9         249  
6 9     9   45 use BusyBird::Log qw(bblog);
  9         16  
  9         411  
7 9     9   44 use BusyBird::Config;
  9         13  
  9         168  
8 9     9   34 use Tie::IxHash;
  9         14  
  9         203  
9 9     9   36 use Carp;
  9         19  
  9         480  
10 9     9   43 use Try::Tiny;
  9         15  
  9         7236  
11              
12             our @CARP_NOT = qw(BusyBird::Timeline BusyBird::Config);
13              
14             sub new {
15 63     63 1 254738 my ($class) = @_;
16 63         503 tie(my %timelines, 'Tie::IxHash');
17 63         1367 my $self = bless {
18             timelines => \%timelines,
19             config => BusyBird::Config->new(type => "global", with_default => 1),
20             }, $class;
21 63         166 return $self;
22             }
23              
24             sub timeline {
25 128     128 1 29917 my ($self, $name) = @_;
26 128         318 my $timeline = $self->get_timeline($name);
27 128 100       985 if(not defined $timeline) {
28 112         250 $timeline = $self->create_timeline($name);
29 112         305 $self->install_timeline($timeline);
30             }
31 128         1554 return $timeline;
32             }
33              
34             sub create_timeline {
35 114     114 1 445 my ($self, $name) = @_;
36 114         316 return BusyBird::Timeline->new(name => $name, storage => $self->get_config("default_status_storage"));
37             }
38              
39             sub get_timeline {
40 669     669 1 1151 my ($self, $name) = @_;
41 669         2894 return $self->{timelines}{$name};
42             }
43              
44             sub get_all_timelines {
45 30     30 1 1481 my ($self) = @_;
46 30         35 return values %{$self->{timelines}};
  30         159  
47             }
48              
49             sub install_timeline {
50 119     119 1 677 my ($self, $timeline) = @_;
51 119 50       278 if($timeline->name eq "") {
52 0         0 bblog("warn", "Invalid timeline name (it's empty)");
53 0         0 return;
54             }
55 119 100       259 if($timeline->name =~ qr{/}) {
56 10         28 bblog("warn", "Invalid timeline name (it contains /)");
57 10         38 return;
58             }
59 109         311 $self->{timelines}{$timeline->name} = $timeline;
60             }
61              
62             sub uninstall_timeline {
63 6     6 1 68815 my ($self, $name) = @_;
64 6         23 my $timeline = $self->get_timeline($name);
65 6         76 delete $self->{timelines}{$name};
66 6         1093 return $timeline;
67             }
68              
69             sub set_config {
70 76     76 1 478 shift()->{config}->set_config(@_);
71             }
72              
73             sub get_config {
74 574     574 1 4654 shift()->{config}->get_config(@_);
75             }
76              
77             sub get_timeline_config {
78 324     324 1 750 my ($self, $timeline_name, $key) = @_;
79 324         476 my $timeline = $self->get_timeline($timeline_name);
80 324 100       2198 my $timeline_config = defined($timeline) ? $timeline->get_config($key) : undef;
81 324 100       531 return $timeline_config if defined $timeline_config;
82 316         488 return $self->get_config($key);
83             }
84              
85             sub watch_unacked_counts {
86 46     46 1 102427 my ($self, %watch_args) = @_;
87 46         78 my $level = $watch_args{level};
88 46 100       113 $level = 'total' if not defined $level;
89 46         59 my $assumed = $watch_args{assumed};
90 46         48 my $callback = $watch_args{callback};
91 46 100 100     234 if(!defined($assumed) || ref($assumed) ne 'HASH') {
92 5         470 croak 'assumed must be a hash-ref';
93             }
94 41 100 100     174 if(!defined($callback) || ref($callback) ne 'CODE') {
95 5         465 croak "callback must be a code-ref";
96             }
97 36         175 my $watcher = BusyBird::Watcher::Aggregator->new;
98 36         318 foreach my $tl_name (keys %$assumed) {
99 49         138 my $timeline = $self->get_timeline($tl_name);
100 49 100       382 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   39 my ($error, $w, $unacked_counts) = @_;
105 29 50       69 if(defined $error) {
106 0         0 $watcher->cancel();
107 0         0 $callback->("Error from timeline $tl_name: $error", $watcher);
108             }else {
109 29         89 $callback->(undef, $watcher, { $tl_name => $unacked_counts });
110             }
111             }
112 45         294 );
113 45 50       190 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 45         95 $watcher->add($tl_watcher);
117 45 100       1355 last if !$watcher->active;
118             }
119 36 100       175 if(!$watcher->watchers) {
120 4         571 croak "assumed argument does not contain any installed timeline.";
121             }
122 32         218 return $watcher;
123             }
124              
125              
126             1;
127              
128             __END__