line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Cluster::Init::Util; |
2
|
7
|
|
|
7
|
|
45
|
use strict; |
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
245
|
|
3
|
7
|
|
|
7
|
|
36
|
use warnings; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
227
|
|
4
|
7
|
|
|
7
|
|
35
|
use Data::Dump qw(dump); |
|
7
|
|
|
|
|
11
|
|
|
7
|
|
|
|
|
388
|
|
5
|
7
|
|
|
7
|
|
47
|
use Carp; |
|
7
|
|
|
|
|
23
|
|
|
7
|
|
|
|
|
507
|
|
6
|
7
|
|
|
7
|
|
40
|
use Carp::Assert; |
|
7
|
|
|
|
|
13
|
|
|
7
|
|
|
|
|
45
|
|
7
|
|
|
|
|
|
|
# use Storable qw(dclone); |
8
|
7
|
|
|
7
|
|
5915
|
use Event qw(loop unloop unloop_all all_watchers sweep); |
|
7
|
|
|
|
|
105251
|
|
|
7
|
|
|
|
|
60
|
|
9
|
7
|
|
|
7
|
|
1582
|
use Event; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
30
|
|
10
|
7
|
|
|
7
|
|
17390
|
use Event::Stats; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use Time::HiRes qw(time); |
12
|
|
|
|
|
|
|
require Exporter; |
13
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
14
|
|
|
|
|
|
|
our @EXPORT_OK = qw(&debug &run NOOP); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
$Event::DIED = sub { |
17
|
|
|
|
|
|
|
Event::verbose_exception_handler(@_); |
18
|
|
|
|
|
|
|
Event::unloop_all(0); |
19
|
|
|
|
|
|
|
}; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
use constant NOOP => 0; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub debug |
24
|
|
|
|
|
|
|
{ |
25
|
|
|
|
|
|
|
my $debug = $ENV{DEBUG} || 0; |
26
|
|
|
|
|
|
|
return unless $debug; |
27
|
|
|
|
|
|
|
my ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask) = caller(1); |
28
|
|
|
|
|
|
|
my $subline = (caller(0))[2]; |
29
|
|
|
|
|
|
|
my $msg = join(' ',@_); |
30
|
|
|
|
|
|
|
$msg.="\n" unless $msg =~ /\n$/; |
31
|
|
|
|
|
|
|
warn time()." $$ $subroutine,$subline: $msg" if $debug; |
32
|
|
|
|
|
|
|
if ($debug > 1) |
33
|
|
|
|
|
|
|
{ |
34
|
|
|
|
|
|
|
warn _stacktrace(); |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
if ($debug > 2) |
37
|
|
|
|
|
|
|
{ |
38
|
|
|
|
|
|
|
Event::Stats::collect(1); |
39
|
|
|
|
|
|
|
warn sprintf("%d\n%-35s %3s %10s %4s %4s %4s %4s %7s\n", time, |
40
|
|
|
|
|
|
|
"DESC", "PRI", "CBTIME", "PEND", "CARS", "RAN", "DIED", "ELAPSED"); |
41
|
|
|
|
|
|
|
for my $w (reverse all_watchers()) |
42
|
|
|
|
|
|
|
{ |
43
|
|
|
|
|
|
|
my @pending = $w->pending(); |
44
|
|
|
|
|
|
|
my $pending = @pending; |
45
|
|
|
|
|
|
|
my $cars=sprintf("%01d%01d%01d%01d", |
46
|
|
|
|
|
|
|
$w->is_cancelled,$w->is_active,$w->is_running,$w->is_suspended); |
47
|
|
|
|
|
|
|
my ($ran,$died,$elapsed) = $w->stats(60); |
48
|
|
|
|
|
|
|
warn sprintf("%-35s %3d %10d %4d %4s %4d %4d %7.3f\n", |
49
|
|
|
|
|
|
|
$w->desc, |
50
|
|
|
|
|
|
|
$w->prio, |
51
|
|
|
|
|
|
|
$w->cbtime, |
52
|
|
|
|
|
|
|
$pending, |
53
|
|
|
|
|
|
|
$cars, |
54
|
|
|
|
|
|
|
$ran, |
55
|
|
|
|
|
|
|
$died, |
56
|
|
|
|
|
|
|
$elapsed); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub _stacktrace |
62
|
|
|
|
|
|
|
{ |
63
|
|
|
|
|
|
|
my $out=""; |
64
|
|
|
|
|
|
|
for (my $i=1;;$i++) |
65
|
|
|
|
|
|
|
{ |
66
|
|
|
|
|
|
|
my @frame = caller($i); |
67
|
|
|
|
|
|
|
last unless @frame; |
68
|
|
|
|
|
|
|
$out .= "$frame[3] $frame[1] line $frame[2]\n"; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
return $out; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub dq |
74
|
|
|
|
|
|
|
{ |
75
|
|
|
|
|
|
|
my $self=shift; |
76
|
|
|
|
|
|
|
my $e=shift; |
77
|
|
|
|
|
|
|
unless (ref $e->w) |
78
|
|
|
|
|
|
|
{ |
79
|
|
|
|
|
|
|
debug "skipping $e -- no watcher"; |
80
|
|
|
|
|
|
|
return 0; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
my $data=$e->w->data || {}; |
83
|
|
|
|
|
|
|
# warn dump $data; |
84
|
|
|
|
|
|
|
my $event=$data->{_dfa_event}; |
85
|
|
|
|
|
|
|
my $desc= $e->w->desc; |
86
|
|
|
|
|
|
|
debug "$desc: isactive: ". $e->w->is_active; |
87
|
|
|
|
|
|
|
$self->killwatcher($e->w) unless $e->w->is_active; |
88
|
|
|
|
|
|
|
# delete $data->{_dfa_event}; |
89
|
|
|
|
|
|
|
# $self->history($event,$data); |
90
|
|
|
|
|
|
|
unless ($event) |
91
|
|
|
|
|
|
|
{ |
92
|
|
|
|
|
|
|
# my $debug=$ENV{DEBUG}; |
93
|
|
|
|
|
|
|
# $ENV{DEBUG}=3; |
94
|
|
|
|
|
|
|
debug "ouch -- somehow there's no _dfa_event in \$data:\n" |
95
|
|
|
|
|
|
|
.(dump $data)."\n" |
96
|
|
|
|
|
|
|
.(dump $self)."\n" |
97
|
|
|
|
|
|
|
.(dump $e)."\n" |
98
|
|
|
|
|
|
|
; |
99
|
|
|
|
|
|
|
# $ENV{DEBUG}=$debug; |
100
|
|
|
|
|
|
|
return 0; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
debug "$desc: calling tick($event,$data)"; |
103
|
|
|
|
|
|
|
$self->tick($event,$data); |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub event |
107
|
|
|
|
|
|
|
{ |
108
|
|
|
|
|
|
|
my $self=shift; |
109
|
|
|
|
|
|
|
my $event=shift; |
110
|
|
|
|
|
|
|
debug "queue event $event"; |
111
|
|
|
|
|
|
|
my $data=shift || {}; |
112
|
|
|
|
|
|
|
$self->timer($event,{at=>time},$data); |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub watcher |
116
|
|
|
|
|
|
|
{ |
117
|
|
|
|
|
|
|
my $self=shift; |
118
|
|
|
|
|
|
|
my $type=shift; |
119
|
|
|
|
|
|
|
my $event=shift; |
120
|
|
|
|
|
|
|
debug "create $type $event"; |
121
|
|
|
|
|
|
|
my $parm=shift || {}; |
122
|
|
|
|
|
|
|
my $olddata=shift || {}; |
123
|
|
|
|
|
|
|
my $class=ref($self); |
124
|
|
|
|
|
|
|
# make a copy so it doesn't go 'round and 'round |
125
|
|
|
|
|
|
|
my $data = _copy($olddata); |
126
|
|
|
|
|
|
|
# $data = eval(dump($data)); |
127
|
|
|
|
|
|
|
my $desc = "$self $type $event"; |
128
|
|
|
|
|
|
|
unless ($event) |
129
|
|
|
|
|
|
|
{ |
130
|
|
|
|
|
|
|
my $debug=$ENV{DEBUG}; |
131
|
|
|
|
|
|
|
$ENV{DEBUG}=3; |
132
|
|
|
|
|
|
|
debug "oooh -- $type has no event".(dump $self); |
133
|
|
|
|
|
|
|
$ENV{DEBUG}=$debug; |
134
|
|
|
|
|
|
|
return 0; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
$data->{_dfa_event}=$event; |
137
|
|
|
|
|
|
|
$parm->{desc}=$desc; |
138
|
|
|
|
|
|
|
$parm->{cb}=[$self,'dq']; |
139
|
|
|
|
|
|
|
$parm->{data}=$data; |
140
|
|
|
|
|
|
|
# debug $type, $event, $data; |
141
|
|
|
|
|
|
|
my $w = Event->$type(%$parm); |
142
|
|
|
|
|
|
|
# warn $w; |
143
|
|
|
|
|
|
|
$self->watchers($w); |
144
|
|
|
|
|
|
|
return $w; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# deep copy, but pass blessed and other complex refs through unchanged |
148
|
|
|
|
|
|
|
sub _copy |
149
|
|
|
|
|
|
|
{ |
150
|
|
|
|
|
|
|
my $in=shift; |
151
|
|
|
|
|
|
|
my $ref=ref $in; |
152
|
|
|
|
|
|
|
return $in unless $ref; |
153
|
|
|
|
|
|
|
$ref eq "SCALAR" && do {my $out; $$out=$$in; return $out}; |
154
|
|
|
|
|
|
|
$ref eq "ARRAY" && do |
155
|
|
|
|
|
|
|
{ |
156
|
|
|
|
|
|
|
my @out = map {_copy($_)} @$in; |
157
|
|
|
|
|
|
|
return \@out; |
158
|
|
|
|
|
|
|
}; |
159
|
|
|
|
|
|
|
$ref eq "HASH" && do |
160
|
|
|
|
|
|
|
{ |
161
|
|
|
|
|
|
|
my %out; |
162
|
|
|
|
|
|
|
while (my ($key,$val) = each %$in) |
163
|
|
|
|
|
|
|
{ |
164
|
|
|
|
|
|
|
$out{$key}=_copy($val); |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
return \%out; |
167
|
|
|
|
|
|
|
}; |
168
|
|
|
|
|
|
|
return $in; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub watchers |
172
|
|
|
|
|
|
|
{ |
173
|
|
|
|
|
|
|
my $self=shift; |
174
|
|
|
|
|
|
|
my $w=shift; |
175
|
|
|
|
|
|
|
if ($w) |
176
|
|
|
|
|
|
|
{ |
177
|
|
|
|
|
|
|
affirm { ref $w }; |
178
|
|
|
|
|
|
|
push @{$self->{watchers}}, $w; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
my $out="watchers:\n"; |
181
|
|
|
|
|
|
|
for my $x (@{$self->{watchers}}) |
182
|
|
|
|
|
|
|
{ |
183
|
|
|
|
|
|
|
next unless ref $x; |
184
|
|
|
|
|
|
|
$out.="\t".$x->desc."\n"; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
# warn $out; |
187
|
|
|
|
|
|
|
return @{$self->{watchers}}; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub killwatcher |
191
|
|
|
|
|
|
|
{ |
192
|
|
|
|
|
|
|
my $self=shift; |
193
|
|
|
|
|
|
|
my $w=shift; |
194
|
|
|
|
|
|
|
if (ref $w) |
195
|
|
|
|
|
|
|
{ |
196
|
|
|
|
|
|
|
debug "killwatcher ".$w->desc; |
197
|
|
|
|
|
|
|
# let it finish any pending requests -- primarily catching CHLD |
198
|
|
|
|
|
|
|
# sweep() while $w->pending; |
199
|
|
|
|
|
|
|
$w->cancel; |
200
|
|
|
|
|
|
|
my @watchers = grep {$_ && $_!=$w} $self->watchers; |
201
|
|
|
|
|
|
|
$self->{watchers}=\@watchers; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
return $self->watchers; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub idle { shift->watcher('idle', @_) } |
207
|
|
|
|
|
|
|
sub timer { shift->watcher('timer', @_) } |
208
|
|
|
|
|
|
|
sub io { shift->watcher('io', @_) } |
209
|
|
|
|
|
|
|
sub var { shift->watcher('var', @_) } |
210
|
|
|
|
|
|
|
sub sigevent { shift->watcher('signal',@_) } |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub fields |
213
|
|
|
|
|
|
|
{ |
214
|
|
|
|
|
|
|
my $self=shift; |
215
|
|
|
|
|
|
|
my $class = ref $self; |
216
|
|
|
|
|
|
|
affirm { $class }; |
217
|
|
|
|
|
|
|
my @field=@_; |
218
|
|
|
|
|
|
|
for my $field (@field) |
219
|
|
|
|
|
|
|
{ |
220
|
|
|
|
|
|
|
next if $self->can($field); |
221
|
|
|
|
|
|
|
my $var = $class."::".$field; |
222
|
|
|
|
|
|
|
debug "$var"; |
223
|
|
|
|
|
|
|
no strict 'refs'; |
224
|
|
|
|
|
|
|
*$field = sub |
225
|
|
|
|
|
|
|
{ |
226
|
|
|
|
|
|
|
my $self=shift; |
227
|
|
|
|
|
|
|
my $val=shift; |
228
|
|
|
|
|
|
|
$self->{$var}=$val if defined $val; |
229
|
|
|
|
|
|
|
return $self->{$var}; |
230
|
|
|
|
|
|
|
}; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub transit |
235
|
|
|
|
|
|
|
{ |
236
|
|
|
|
|
|
|
my ($self,$oldstate,$newstate,$action,@arg)=@_; |
237
|
|
|
|
|
|
|
my $class = ref $self; |
238
|
|
|
|
|
|
|
my $tag = $self->{tag} || ""; |
239
|
|
|
|
|
|
|
debug "$class: $tag: newstate=>'$newstate', action=>'$action'\n"; |
240
|
|
|
|
|
|
|
$self->{status}->newstate($self,$self->{name},$self->{level},$newstate) |
241
|
|
|
|
|
|
|
if $self->{status} && $self->{name} && $self->{level}; |
242
|
|
|
|
|
|
|
if ($action) |
243
|
|
|
|
|
|
|
{ |
244
|
|
|
|
|
|
|
my $method=lc($action); |
245
|
|
|
|
|
|
|
my $code='$self->'.$method.'(@arg)'; |
246
|
|
|
|
|
|
|
unless ($self->can($method)) |
247
|
|
|
|
|
|
|
{ |
248
|
|
|
|
|
|
|
warn "$code not implemented\n"; |
249
|
|
|
|
|
|
|
return undef; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
else |
252
|
|
|
|
|
|
|
{ |
253
|
|
|
|
|
|
|
my ($event,@res) = eval ($code); |
254
|
|
|
|
|
|
|
unless(defined $event) |
255
|
|
|
|
|
|
|
{ |
256
|
|
|
|
|
|
|
die "$class: '$code' died: $@\n"; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
debug "$class: '$code' returned '$event'\n"; |
259
|
|
|
|
|
|
|
$self->event($event,@res) if $event; # =~ /^[A-Z]+[A-Z0-9]+$/; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
# $self->timer("foo",{at=>time}); |
263
|
|
|
|
|
|
|
# $DB::single=1 if $newstate eq "DONE"; |
264
|
|
|
|
|
|
|
# `strace -o /tmp/t1 -p $$` if $newstate eq "DONE"; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub run |
268
|
|
|
|
|
|
|
{ |
269
|
|
|
|
|
|
|
my $seconds=shift; |
270
|
|
|
|
|
|
|
Event->timer(at=>time() + $seconds,cb=>sub{unloop()}); |
271
|
|
|
|
|
|
|
loop(); |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
sub destruct |
275
|
|
|
|
|
|
|
{ |
276
|
|
|
|
|
|
|
my $self=shift; |
277
|
|
|
|
|
|
|
my $debug="destruct "; |
278
|
|
|
|
|
|
|
$debug.= $self->{tag} || $self; |
279
|
|
|
|
|
|
|
$debug.=" "; |
280
|
|
|
|
|
|
|
$debug.= $self->{name} || " "; |
281
|
|
|
|
|
|
|
$debug.=" "; |
282
|
|
|
|
|
|
|
$debug.= $self->{pid} || " "; |
283
|
|
|
|
|
|
|
debug $debug; |
284
|
|
|
|
|
|
|
if ($self->{pid}) |
285
|
|
|
|
|
|
|
{ |
286
|
|
|
|
|
|
|
debug "killing ".$self->{pid}; |
287
|
|
|
|
|
|
|
kill(-9, $self->{pid}); |
288
|
|
|
|
|
|
|
kill(9, $self->{pid}); |
289
|
|
|
|
|
|
|
# the following line is dangerous -- could hang on hung umount |
290
|
|
|
|
|
|
|
# requests etc. |
291
|
|
|
|
|
|
|
waitpid($self->{pid},0); |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
for my $w ($self->watchers) |
294
|
|
|
|
|
|
|
{ |
295
|
|
|
|
|
|
|
$self->killwatcher($w); |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
$self->{status}->remove($self,$self->{name}) |
298
|
|
|
|
|
|
|
if $self->{status} && $self->{name}; |
299
|
|
|
|
|
|
|
return 1; |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
sub DESTROY |
303
|
|
|
|
|
|
|
{ |
304
|
|
|
|
|
|
|
my $self=shift; |
305
|
|
|
|
|
|
|
$self->destruct; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
1; |