| File: | blib/lib/App/ABAN/WipeProgress.pm |
| Coverage: | 96.6% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package App::ABAN::WipeProgress; | ||||||
| 2 | # ABSTRACT: Internal library to track wiper progress | ||||||
| 3 | 1 1 1 | 56626 4662 2 | use Moo; | ||||
| 4 | 1 1 1 | 785 1 32 | use Carp; | ||||
| 5 | 1 1 1 | 3 2 3 | use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC); | ||||
| 6 | |||||||
| 7 | |||||||
| 8 | has first_interval => ( #seconds | ||||||
| 9 | is => 'ro', | ||||||
| 10 | default => sub { 2 }, | ||||||
| 11 | ); | ||||||
| 12 | |||||||
| 13 | |||||||
| 14 | |||||||
| 15 | has interval => ( # seconds | ||||||
| 16 | is => 'rw', | ||||||
| 17 | default => sub { 60 }, | ||||||
| 18 | ); | ||||||
| 19 | |||||||
| 20 | |||||||
| 21 | |||||||
| 22 | has remaining => ( | ||||||
| 23 | is => 'rw', | ||||||
| 24 | trigger => 1, | ||||||
| 25 | lazy => 1, | ||||||
| 26 | default => sub { shift->_initial_work }, | ||||||
| 27 | init_arg => undef, | ||||||
| 28 | ); | ||||||
| 29 | |||||||
| 30 | |||||||
| 31 | |||||||
| 32 | has extra => ( | ||||||
| 33 | is => 'rw', | ||||||
| 34 | ); | ||||||
| 35 | |||||||
| 36 | |||||||
| 37 | |||||||
| 38 | has overall_rate => ( # bytes/sec | ||||||
| 39 | is => 'rwp', | ||||||
| 40 | ); | ||||||
| 41 | |||||||
| 42 | |||||||
| 43 | |||||||
| 44 | has current_rate => ( # bytes/sec | ||||||
| 45 | is => 'rwp', | ||||||
| 46 | ); | ||||||
| 47 | |||||||
| 48 | |||||||
| 49 | |||||||
| 50 | sub etr { | ||||||
| 51 | 3 | 1 | 1464 | my $self = shift; | |||
| 52 | 3 | 36 | return $self->overall_rate | ||||
| 53 | ? $self->remaining / $self->overall_rate | ||||||
| 54 | : undef; | ||||||
| 55 | } | ||||||
| 56 | |||||||
| 57 | |||||||
| 58 | sub done { | ||||||
| 59 | 1 | 1 | 725 | my ($self) = @_; | |||
| 60 | 1 | 3 | my $now = clock_gettime(CLOCK_MONOTONIC); | ||||
| 61 | |||||||
| 62 | 1 | 5 | $self->_update_progress($now, 1); | ||||
| 63 | 1 | 5 | $self->_display_progress($now); | ||||
| 64 | |||||||
| 65 | 1 | 5 | return; | ||||
| 66 | } | ||||||
| 67 | |||||||
| 68 | |||||||
| 69 | has _initial_work => ( # bytes | ||||||
| 70 | is => 'ro', | ||||||
| 71 | init_arg => 'remaining', | ||||||
| 72 | ); | ||||||
| 73 | |||||||
| 74 | |||||||
| 75 | |||||||
| 76 | has _initial_time => ( | ||||||
| 77 | is => 'ro', | ||||||
| 78 | default => sub { clock_gettime(CLOCK_MONOTONIC) }, | ||||||
| 79 | ); | ||||||
| 80 | |||||||
| 81 | |||||||
| 82 | |||||||
| 83 | has _next_progress => ( | ||||||
| 84 | is => 'rw', | ||||||
| 85 | lazy => 1, | ||||||
| 86 | default => | ||||||
| 87 | sub { my $self = shift; $self->_initial_time + $self->first_interval }, | ||||||
| 88 | ); | ||||||
| 89 | |||||||
| 90 | |||||||
| 91 | |||||||
| 92 | has _last_work => ( | ||||||
| 93 | is => 'rw', | ||||||
| 94 | lazy => 1, | ||||||
| 95 | default => sub { shift->_initial_work }, | ||||||
| 96 | ); | ||||||
| 97 | |||||||
| 98 | |||||||
| 99 | |||||||
| 100 | has _last_time => ( | ||||||
| 101 | is => 'rw', | ||||||
| 102 | lazy => 1, | ||||||
| 103 | default => sub { shift->_initial_time }, | ||||||
| 104 | ); | ||||||
| 105 | |||||||
| 106 | |||||||
| 107 | |||||||
| 108 | has _display => ( | ||||||
| 109 | is => 'rw', | ||||||
| 110 | ); | ||||||
| 111 | |||||||
| 112 | |||||||
| 113 | sub _trigger_remaining { | ||||||
| 114 | 6 | 6507390 | my ($self) = @_; | ||||
| 115 | |||||||
| 116 | 6 | 24 | my $now = clock_gettime(CLOCK_MONOTONIC); | ||||
| 117 | 6 | 65 | my $display = ($now >= $self->_next_progress); | ||||
| 118 | |||||||
| 119 | 6 | 40 | $self->_update_progress($now, $display); | ||||
| 120 | 6 | 14 | $self->_display_progress($now) if $display; | ||||
| 121 | 6 | 33 | $self->_next_progress($now + $self->interval) if $display; | ||||
| 122 | |||||||
| 123 | 6 | 23 | return; | ||||
| 124 | } | ||||||
| 125 | |||||||
| 126 | |||||||
| 127 | sub _update_progress { | ||||||
| 128 | 7 | 17 | my ($self, $now, $displaying) = @_; | ||||
| 129 | 7 | 52 | my $remaining = $self->remaining; | ||||
| 130 | |||||||
| 131 | # opposite orders since we're counting down in remaining work and up | ||||||
| 132 | # in time. | ||||||
| 133 | 7 | 55 | $self->_set_overall_rate( | ||||
| 134 | ($self->_initial_work - $remaining) / ($now - $self->_initial_time)); | ||||||
| 135 | |||||||
| 136 | 7 | 16 | if ($displaying) { | ||||
| 137 | 3 | 22 | $self->_set_current_rate( | ||||
| 138 | ($self->_last_work - $remaining) / ($now - $self->_last_time)); | ||||||
| 139 | 3 | 55 | $self->_last_work($remaining); | ||||
| 140 | 3 | 28 | $self->_last_time($now); | ||||
| 141 | } | ||||||
| 142 | |||||||
| 143 | 7 | 17 | return; | ||||
| 144 | } | ||||||
| 145 | |||||||
| 146 | |||||||
| 147 | |||||||
| 148 | sub _display_progress { | ||||||
| 149 | 3 | 7 | my ($self, $now) = @_; | ||||
| 150 | |||||||
| 151 | 3 | 11 | $self->_display | ||||
| 152 | and return $self->_display->($self, $now); | ||||||
| 153 | |||||||
| 154 | 1 | 5 | my $extra | ||||
| 155 | = defined $self->extra | ||||||
| 156 | ? (': ' . $self->extra->($self)) | ||||||
| 157 | : ''; | ||||||
| 158 | |||||||
| 159 | 1 | 10 | printf STDERR "%0.0fm elapsed, %0.0f/%0.0f GiB done, %0.1f MB/sec (%0.1f now), ETR %ih%2im%s\n", | ||||
| 160 | ($now-$self->_initial_time)/60, | ||||||
| 161 | ($self->_initial_work - $self->remaining)/(1024**3), | ||||||
| 162 | $self->_initial_work/(1024**3), | ||||||
| 163 | $self->overall_rate/(1024**2), | ||||||
| 164 | $self->current_rate/(1024**2), | ||||||
| 165 | int($self->etr/3600), | ||||||
| 166 | int(($self->etr%3600)/60), | ||||||
| 167 | $extra; | ||||||
| 168 | |||||||
| 169 | 1 | 379 | return; | ||||
| 170 | } | ||||||
| 171 | |||||||
| 172 | |||||||
| 173 | 1; | ||||||
| 174 | |||||||