BusyBird::Main - main application object of BusyBird


    use BusyBird::Main;
    my $main = BusyBird::Main->new;
    my $foo = $main->timeline("foo");
    my $bar = $main->timeline("bar");
    my @all_timelines = $main->get_all_timelines;
    $all_timelines[0]->name; ## => "foo"
    $all_timelines[1]->name; ## => "bar"
    $main->set_config(time_zone => "UTC");
    $foo->set_config(time_zone => "+0900");
    $main->get_timeline_config("foo", "time_zone"); ## => "+0900"
    $main->get_timeline_config("bar", "time_zone"); ## => "UTC"


BusyBird::Main is the main application object of BusyBird. It keeps application configuration and timelines (BusyBird::Timeline objects).

BusyBird::Main does not depend on PSGI or any other controller mechanism. If you want to create PSGI application from BusyBird::Main, check out BusyBird::Main::PSGI class.

This module uses BusyBird::Log for logging.


$main = BusyBird::Main->new()

Creates a BusyBird::Main object.

Users usually don't have to call this method. The singleton instance of BusyBird::Main object is maintained by BusyBird module. See BusyBird and BusyBird::Manual::Tutorial for detail.


$timeline = $main->timeline($name)

Returns the $timeline whose name is $name from the $main. $timeline is a BusyBird::Timeline object. If $name includes Unicode characters, it must be a character string (decoded string), not a binary string (encoded string).

If there is no timeline named $name in $main, a new timeline is created, installed and returned.

In BusyBird::Main, timeline names must not contain a slash "/", because it confuses Web API. If $name contains a slash, the timeline IS created and returned, but it's NOT installed in the $main object. In that case, it logs a warning message.

If a new timeline is created by this method, it uses the StatusStorage object given by $main->get_config("default_status_storage") for that timeline. See BusyBird::Manual::Config for defail.

$timeline = $main->create_timeline($name)

Creates and returns a $timeline like timeline() method does, but not install it.

This method always creates a new BusyBird::Timeline object.

$timeline = $main->get_timeline($name)

Returns the $timeline whose name is $name from the $main.

If there is no timeline named $name in $main, it returns undef.

@timelines = $main->get_all_timelines()

Returns the list of all timelines installed in the $main.


Installs the given $timeline to the $main.

If a timeline with the same name as the given $timeline is already installed in the $main, the old timeline is replaced by the given $timeline.

You cannot install $timeline whose name contains a slash "/". In this case, the $timeline is ignored and it logs a warning message.

$timeline = $main->uninstall_timeline($name)

Uninstalls the timeline whose name is $name from the $main. It returns the uninstalled $timeline.

If there is no timeline named $name, it returns undef.

$main->set_config($key1 => $value1, $key2 => $value2, ...)

Sets config parameters to the $main.

$key1, $key2, ... are the keys for the config parameters, and $value1, $value2, ... are the values for them.

See BusyBird::Manual::Config for the list of config parameters.

$value = $main->get_config($key)

Returns the value of config parameter whose key is $key.

If there is no config parameter associated with $key, it returns undef.

$value = $main->get_timeline_config($timeline_name, $key)

Returns the value of config parameter for a timeline.

If config item $key is defined in the timeline specified by $timeline_name, it returns the config value from the timeline. Otherwise, it returns the config value in the $main object. If both the timeline and the $main does not have the config value for $key, it returns undef.

$watcher = $main->watch_unacked_counts(%args)

Watches updates in numbers of unacked statuses (i.e. unacked counts) in timelines.

Fields in %args are as follows.

level => {'total', NUMBER} (optional, default: 'total')

Specifies the status level you want to watch.

assumed => HASHREF (mandatory)

Specifies the assumed unacked counts in the status level for each timeline.

callback => CODEREF($error, $w, $tl_unacked_counts) (mandatory)

Specifies the callback function that is called when the assumed unacked counts are different from the current unacked counts.

When this method is called, the current unacked counts are compared with the unacked counts given in the arguments (level and assumed arguments). If the current and assumed unacked counts are different, the callback subroutine reference is called with the current unacked counts ($tl_unacked_counts). If the current and assumed unacked counts are the same, the execution of the callback is delayed until there is some difference between them.

level argument is the status level you want to watch. It is either an integer number or the string of 'total'. If an integer is specified, the unacked counts in that status level are watched. If 'total' is specified, the total unacked counts are watched.

assumed argument is a hash-ref specifying the assumed unacked count for each timeline. Its key is the name of the timeline you want to watch, and its value is the assumed unacked counts for the timeline in the status level specified by level. You can watch multiple timelines by a single call of this method.

In success, the callback function is called with three arguments ($error, $w and $tl_unacked_counts). $error is undef. $w is an BusyBird::Watcher object representing the watch. $tl_unacked_counts is a hash-ref describing the current unacked counts for watched timelines.

In failure, the argument $error is a truthy value describing the error. $w is an inactive BusyBird::Watcher.

For example,

    use Data::Dumper;
    my $watcher = $main->watch_unacked_counts(
        level => "total",
        assumed => { TL1 => 0, TL2 => 0, TL3 => 5 },
        callback => sub {
            my ($error, $w, $tl_unacked_counts) = @_;
            print Dumper $tl_unacked_counts;

The level and assumed parameters in the above example mean that the caller assumes there is no unacked statuses in TL1 and TL2, and there are 5 unacked statuses in TL3.

$tl_unacked_counts represents the current unacked counts. It's something like

    $tl_unacked_counts = {
        TL1 => {
            total => 2,
            0     => 1,
            2     => 1,

This means the timeline named 'TL1' actually has 2 unacked statuses in total, one of which is in level 0 and the other is in level 2.

Note that although you can specify multiple timelines in assumed, the returned $tl_unacked_counts may not contain all the specified timelines.

The return value of this method ($watcher) is the same instance as $w. You can use $watcher->cancel() or $w->cancel() method to cancel the watch, like we did in the above example. Otherwise, the callback is repeatedly called whenever some updates in unacked counts happen and the current and assumed unacked counts are different.

In assumed argument, the timeline names that are not in $main are ignored. If there is no existent timeline name in assumed, this method croaks.

Never apply future_of() function from BusyBird::Util to this method. This is because this method can execute the callback more than once.


Toshio Ito <toshioito [at]>