3 use base qw(Gearman::Driver::Worker);
5 use Time::HiRes qw(time);
6 use Data::Dump qw(dump);
9 with 'APKPM::Gearman::Client';
10 with 'APKPM::Gearman';
12 sub prefix { 'poll_' }
14 sub by_prefix : Job : Encode(e_json) {
15 my ( $self, $job, $workload ) = @_;
17 my $redis = Redis->new;
18 $redis->del( $_ ) foreach $redis->keys('poll.*');
20 my $start = $self->datetime_now;
22 $redis->set( 'poll.start' => $start );
24 my $entries = $self->do( 'LDAP_search' => "(&(cn=$workload*)(dhcpStatements=*))" );
27 foreach my $entry ( @$entries ) {
28 $ip_username->{ $entry->{cn} } = $1 if $entry->{dhcpStatements} =~ m/fixed-address\s+(\S+)/;
31 my $taskset = $self->gc->new_task_set;
33 while (my ($username,$ip) = each %$ip_username) {
34 $taskset->add_task('poll_ip_username', "$ip $username", {
35 on_complete => sub { push @$results, ${$_[0]} }
37 $redis->sadd('poll.queued' => $ip);
43 my $finish = $self->datetime_now;
44 $redis->set( 'poll.finish' => $finish );
46 my $poll = { _table => 'poll' }; # Store_insert_table arg
48 foreach my $k ( $redis->keys('poll.*') ) {
52 $poll->{$n} = eval { $redis->scard($k) } || $redis->get($k);
56 $self->do_background_json('Store_insert_table', $poll);
58 return { ldap => $ip_username, results => $results, poll => $poll };
61 sub ip_username : Job : Decode(d_array) : Encode(e_json) {
62 my ( $self, $job, $workload ) = @_;
64 my ( $ip, $username ) = @$workload;
66 return { error => "invalid workload", expected => "ip username" } unless $ip && $username;
67 my $ping = $self->do('ping', $ip);
69 my $redis = Redis->new;
71 if ( exists $ping->{error} ) {
72 warn "XXX error: $ip";
73 $redis->sadd( 'poll.ping.error' => $ip );
76 $redis->sadd( 'poll.ping.ok' => $ip );
79 $ping->{username} = $username;
80 $self->do_background_json( 'Store_ping', $ping );
82 $self->do_background( 'Davolink_info', "$ip $username adsl" );