Log-Any-Progress

 view release on metacpan or  search on metacpan

lib/Log/Any/Progress.pm  view on Meta::CPAN


    return $self;
}

=head2 start

  my $progress = Log::Any::Progress->new(
      count => $num_things_to_do,
      delayed_start => 1,  # don't start the timer yet
  );

  # Do some other work here that might take some time...

  $progress->start;

  foreach my $thing_to_do (@things_to_do) {
      do_the_thing($thing_to_do);
      $progress->update;
  }

Initialize (or reinitialize) the progress object by resetting the
start time, elapsed time, etc.

This is normally called automatically at object construction time
unless L</delayed_start> is specified, in which case it should be
called explicitly at the appropriate time.

Initializing the progress object (whether done automatically or
manually) causes the first log message to be emitted.

=cut

sub start { shift->update(0) }

=head2 update

  my $progress = Log::Any::Progress->new(
      count => $num_things_to_do,
  );

  foreach my $thing_to_do (@things_to_do) {
      do_the_thing($thing_to_do);
      $progress->update;
  }

Update the iteration count within the progress object and maybe emit
a corresponding log message showing the current progress statistics
(depending on timing and the value of L</min_sec_between_messages>).

Calling C<update> with no arguments increments the internal iteration
count by one.  A positive interger may be passed as an argument to
explicitly update the iteration count to a particular value.

Once the iteration count reaches the specified L</count> value, the
progress is considered to be complete and a final log message is
emitted with summary statistics, and subsequent calls to C<update>
will have no effect.

=cut

sub update
{
    my ($self, $current_iteration) = @_;

    if (defined $current_iteration) {
        $self->{_current_iteration} = $current_iteration;
    }
    else {
        $current_iteration = ++$self->{_current_iteration};
    }

    return if $current_iteration < 0;

    # Allow for reinitialization even if finished:
    return if $self->{_finished} && $current_iteration != 0;

    my $now = [ gettimeofday ];

    my $have_count = $self->{count} > 0;

    if ($current_iteration == 0 || !$self->{_initialized}) {
        $self->{_time_elapsed}      = 0;
        $self->{_time_start}        = $now;
        $self->{_time_last_log}     = $now;
        $self->{_current_iteration} = $current_iteration;
        $self->{_finished}          = 0;
        $self->{_initialized}       = 1;

        my $level  = $self->{log_level_start_finish};
        my $format = $have_count
                         ? $self->{prefix} . ': Iteration:0/%d 0%% STARTING'
                         : $self->{prefix} . ': Iteration:0 STARTING';
        $self->{logger}->$level(
            $format,
            $self->{count},
        );
    }

    return if $current_iteration == 0;

    $self->{_time_elapsed} = tv_interval $self->{_time_start}, $now;

    my $elapsed_sec = $self->{_time_elapsed};
    my $elapsed     = $self->format_seconds($elapsed_sec);

    my $avg_sec = $self->{_time_elapsed} / $current_iteration;
    my $avg     = $self->format_seconds($avg_sec);

    if ($have_count && $current_iteration >= $self->{count}) {

        $self->{_current_iteration} = $current_iteration = $self->{count};
        $self->{_finished} = 1;

        my $level = $self->{log_level_start_finish};
        $self->{logger}->$level(
            $self->{prefix} . ': Iteration:%d/%d 100%% FINISHED Elapsed:%s Avg:%s',
            $current_iteration,
            $self->{count},
            $elapsed,
            $avg,
        );



( run in 1.129 second using v1.01-cache-2.11-cpan-39bf76dae61 )