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 $name
s 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:
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Dancer-Plugin-Progress
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.