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 |