NAME

Dancer::Plugin::Progress - Dancer plugin to display a progress bar during long-running requests

VERSION

version 0.1

DESCRIPTION

This plugin helps you displaying a progress bar during long-running requests (routes that take multiple seconds to finish, for example due to network latency to a backend).

SYNOPSIS

use Dancer::Plugin::Progress;
use AnyEvent;

get '/some_timer' => sub {
    long_running 'some_timer', 5, sub {
        my $state = shift;

        $state->{timer} =
        AnyEvent->timer(after => 1, interval => 1, cb => sub {
            if (++$state->{cnt} == 5) {
                undef $state->{timer};
                finished 'some_timer';
            } else {
                progress 'some_timer' => $state->{cnt};
            }
        });
    };

    template 'progressbar', { name => 'some_timer' };
};

Then set up a template like this:

<div id="progress">Please enable JavaScript</div>

<script type="text/javascript">
function pollProgress(name, interval) {
    $.getJSON('/_progress/' + name, function(pg) {
        if (pg.progress === null) {
            $('#progress').text('done!');
            return;
        }
        $('#progress').text('progress: ' + pg.progress + ' / ' + pg.max);
        setTimeout(function() {
                pollProgress(name, interval);
            }, interval);
    });
}

$(document).ready(function() {
    pollProgress('<% name %>', 1000);
});
</script>

METHODS

long_running($name, $max, $init)

Sets up the necessary state. The $name identifies this request in the user's session, so you need to chose different $names for different operations. $max specifies the maximum progress, so if you plan to make 5 requests to your backend until this operation is complete, set $max to 5. If you don't need it, just set it to 0.

$init should be a CodeRef to trigger your operation (to initialize a timer, some asynchronous HTTP request, etc.). It will be called with a HashRef to the initial state that Dancer::Plugin::Progress keeps for this operation, so you can put your AnyEvent guards in there for example.

progress($name[, $progress[, $data]])

If called with a single argument, this returns a hash describing the current progress:

{
    progress => 1,
    max => 5,
    data => "some data"
}

If called with a $progress argument, it updates the progress. You can use any scalar here, Dancer::Plugin::Progress will just use it without making any assumptions.

Additionally, you can pass $data. While there is no difference between $progress and $data (both are arbitrary scalars), it makes the separation between a linear progress (step 2 of 5) plus an additional status message ("requesting http://www.slashdot.org/") more clear.

finished($name)

Marks the operation as finished. At the next request polling the progress, null is returned as 'progress' member of the hash and the state is cleaned up (that means you must not poll the request after receiving a hash with 'progress':null).

When calling finished, you should also undef your guard objects, if any.

INNER WORKINGS

Dancer::Plugin::Progress keeps state by generating a unique ID for every call of long_running with the same $name parameter and stores the ID in the user's session under the key '_running'.

A route handler is installed for '/_progress/:name', which should be polled (we resort to polling due to the lack of better mechanisms in Dancer/jQuery) by the user.

AUTHOR

Michael Stapelberg, <michael at stapelberg.de>

BUGS

Please report any bugs or feature requests to bug-dancer-plugin-progress at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Dancer-Plugin-Progress. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Dancer::Plugin::Progress

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright 2010 Michael Stapelberg.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.