store poll.* runtime data in redis
[APKPM.git] / lib / APKPM / Poll.pm
1 package APKPM::Poll;
2
3 use base qw(Gearman::Driver::Worker);
4 use Moose;
5 use Time::HiRes;
6 use Data::Dump qw(dump);
7 use Redis;
8
9 with 'APKPM::Gearman::Client';
10 with 'APKPM::Gearman';
11
12 sub prefix { 'poll_' }
13
14 sub by_prefix : Job : MinProcesses(1) : MaxProcesses(1) : Encode(e_json) {
15         my ( $self, $job, $workload ) = @_;
16
17         my $entries = $self->do( 'LDAP_search' => "(&(cn=$workload*)(dhcpStatements=*))" );
18
19         my $ip_username;
20         foreach my $entry ( @$entries ) {
21                 $ip_username->{ $entry->{cn} } = $1 if $entry->{dhcpStatements} =~ m/fixed-address\s+(\S+)/;
22         }
23
24         my $redis = Redis->new;
25         $redis->del( $_ ) foreach $redis->keys('poll.*');
26
27         my $taskset = $self->gc->new_task_set;
28         my $results;
29         while (my ($username,$ip) = each %$ip_username) {
30                 $taskset->add_task('poll_ip_username', "$ip $username", {
31                         on_complete => sub { push @$results, ${$_[0]} }
32                 });
33                 $redis->sadd('poll.queued' => $ip);
34         }
35
36         warn "# wait";
37         $taskset->wait;
38
39         return { ldap => $ip_username, results => $results };
40 }
41
42 sub ip_username : Job : MinProcesses(1) : MaxProcesses(25) : Decode(d_array) : Encode(e_json) {
43         my ( $self, $job, $workload ) = @_;
44
45         my ( $ip, $username ) = @$workload;
46
47         return { error => "invalid workload", expected => "ip username" } unless $ip && $username;
48         my $ping = $self->do('ping', $ip);
49
50         my $redis = Redis->new;
51
52         if ( exists $ping->{error} ) {
53 warn "XXX error: $ip";
54                 $redis->sadd( 'poll.ping.error' => $ip );
55                 return $ping;
56         } else {
57                 $redis->sadd( 'poll.ping.ok' => $ip );
58         }
59
60         $ping->{username} = $username;
61         $self->do_background_json( 'Store_ping', $ping );
62
63         $self->do_background( 'Davolink_info', "$ip $username adsl" );
64
65         return $ping;
66 }
67
68 1;