Clock.pm 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # ex:ts=8 sw=4:
  2. # $OpenBSD: Clock.pm,v 1.8 2015/08/11 22:39:57 espie Exp $
  3. #
  4. # Copyright (c) 2011-2013 Marc Espie <espie@openbsd.org>
  5. #
  6. # Permission to use, copy, modify, and distribute this software for any
  7. # purpose with or without fee is hereby granted, provided that the above
  8. # copyright notice and this permission notice appear in all copies.
  9. #
  10. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. use strict;
  18. use warnings;
  19. # everything needed to handle clock
  20. use Time::HiRes qw(time);
  21. # explicit stop/restart clock where needed
  22. package DPB::Clock;
  23. # users will register/unregister, they must have a
  24. # stopped_clock($gap) method to adjust.
  25. my $items = {};
  26. sub register
  27. {
  28. my ($class, $o) = @_;
  29. $items->{$o} = $o;
  30. }
  31. sub unregister
  32. {
  33. my ($class, $o) = @_;
  34. delete $items->{$o};
  35. }
  36. my $stopped_clock;
  37. sub stop
  38. {
  39. $stopped_clock = time();
  40. }
  41. sub restart
  42. {
  43. my $gap = time() - $stopped_clock;
  44. for my $o (values %$items) {
  45. $o->stopped_clock($gap, $stopped_clock);
  46. }
  47. }
  48. # tasks with a timer
  49. package DPB::Task::Clocked;
  50. our @ISA = qw(DPB::Task::Fork);
  51. sub fork
  52. {
  53. my ($self, $core) = @_;
  54. $self->{started} = time();
  55. DPB::Clock->register($self);
  56. return $self->SUPER::fork($core);
  57. }
  58. sub finalize
  59. {
  60. my ($self, $core) = @_;
  61. $self->{ended} = time();
  62. DPB::Clock->unregister($self);
  63. return $self->SUPER::finalize($core);
  64. }
  65. sub elapsed
  66. {
  67. my $self = shift;
  68. return $self->{ended} - $self->{started};
  69. }
  70. sub stopped_clock
  71. {
  72. my ($self, $gap) = @_;
  73. $self->{started} += $gap;
  74. }
  75. # how to know if we're stuck: we watch some file size.
  76. # if there's some expected value, then we can display a %
  77. package DPB::Watch;
  78. sub new
  79. {
  80. my ($class, $file, $expected, $offset, $time) = @_;
  81. my $o = bless {
  82. file => $file,
  83. expected => $expected,
  84. offset => $offset,
  85. time => $time,
  86. max => 0,
  87. }, $class;
  88. DPB::Clock->register($o);
  89. return $o;
  90. }
  91. sub check_change
  92. {
  93. my ($self, $current) = @_;
  94. $self->{time} //= $current;
  95. my $sz = ($self->{file}->stat)[7];
  96. if (defined $sz && defined $self->{offset}) {
  97. $sz -= $self->{offset};
  98. }
  99. if ((defined $sz &&
  100. (!defined $self->{sz} || $self->{sz} != $sz)) ||
  101. (!defined $sz && defined $self->{sz})) {
  102. $self->{sz} = $sz;
  103. $self->{time} = $current;
  104. }
  105. my $d = $current - $self->{time};
  106. if ($d > $self->{max}) {
  107. $self->{max} = $d;
  108. }
  109. return $d;
  110. }
  111. sub percent_message
  112. {
  113. my $self = shift;
  114. my $progress = '';
  115. if (defined $self->{sz}) {
  116. if (defined $self->{expected} &&
  117. $self->{sz} < 4 * $self->{expected}) {
  118. $progress = ' '.
  119. int($self->{sz}*100/$self->{expected}). '%';
  120. } else {
  121. $progress = ' '.$self->{sz};
  122. }
  123. }
  124. return $progress;
  125. }
  126. sub frozen_message
  127. {
  128. my ($self, $diff) = @_;
  129. my $unchanged = " frozen for ";
  130. if ($diff > 7200) {
  131. $unchanged .= int($diff/3600)." HOURS!";
  132. } elsif ($diff > 300) {
  133. $unchanged .= int($diff/60)."mn";
  134. } elsif ($diff > 10) {
  135. $unchanged .= int($diff)."s";
  136. } else {
  137. $unchanged = "";
  138. }
  139. return $unchanged;
  140. }
  141. sub reset_offset
  142. {
  143. my $self = shift;
  144. my $sz = ($self->{file}->stat)[7];
  145. if (defined $sz) {
  146. $self->{offset} = $sz;
  147. }
  148. }
  149. sub stopped_clock
  150. {
  151. my ($self, $gap) = @_;
  152. $self->{time} += $gap if defined $self->{time};
  153. }
  154. sub DESTROY
  155. {
  156. DPB::Clock->unregister(shift);
  157. }
  158. 1;