don't try to encode non-references
[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 qw(time);
6 use Data::Dump qw(dump);
7 use Redis;
8
9 with 'APKPM::Gearman::Client';
10 with 'APKPM::Gearman';
11
12 sub prefix { '' }
13
14 sub poll_prefix : Job : Encode(e_json) {
15         my ( $self, $job, $workload ) = @_;
16
17         my $redis = Redis->new;
18         $redis->del( $_ ) foreach $redis->keys('poll.*');
19
20         my $start = $self->datetime_now;
21
22         $redis->set( 'poll.start' => $start );
23
24         my $entries = $self->do( 'LDAP_search' => "(&(cn=$workload*)(dhcpStatements=*))" );
25
26         my $ip_username;
27         foreach my $entry ( @$entries ) {
28                 $ip_username->{ $entry->{cn} } = $1 if $entry->{dhcpStatements} =~ m/fixed-address\s+(\S+)/;
29         }
30
31         my $taskset = $self->gc->new_task_set;
32         my $results;
33         while (my ($username,$ip) = each %$ip_username) {
34                 $taskset->add_task('poll_ip_username', "$ip $username", {
35                         on_complete => sub { push @$results, ${$_[0]} }
36                 });
37                 $redis->sadd('poll.queued' => $ip);
38         }
39
40         warn "# wait";
41         $taskset->wait;
42
43         my $finish = $self->datetime_now;
44         $redis->set( 'poll.finish' => $finish );
45
46         my $poll;
47         foreach my $k ( $redis->keys('poll.*') ) {
48                 my $n = $k;
49                 $n =~ s/^poll\.//;
50                 $n =~ s/\./_/g;
51                 $poll->{$n} = eval { $redis->scard($k) } || $redis->get($k);
52         }
53
54         warn dump $poll;
55         $self->do_background_json('Store_insert', { _table => 'poll', %$poll });
56
57         return { ldap => $ip_username, results => $results, poll => $poll };
58 }
59
60 sub poll_ip_username : Job : Decode(d_array) : Encode(e_json) {
61         my ( $self, $job, $workload ) = @_;
62
63         my ( $ip, $username ) = @$workload;
64
65         return { error => "invalid workload", expected => "ip username" } unless $ip && $username;
66         my $ping = $self->do('ping', $ip);
67
68         my $redis = Redis->new;
69
70         if ( exists $ping->{error} ) {
71 warn "XXX error: $ip";
72                 $redis->sadd( 'poll.ping.error' => $ip );
73                 return $ping;
74         } else {
75                 $redis->sadd( 'poll.ping.ok' => $ip );
76         }
77
78         $ping->{username} = $username;
79         $ping->{timestamp} = $self->datetime_now;
80         $self->do_background_json( 'Store_insert', {
81                  _table => 'ping',
82                 username => $username,
83                 timestamp => $self->datetime_now,
84                 %$ping
85         });
86
87         $self->do_background( 'Davolink_info', "$ip $username adsl" );
88
89         return $ping;
90 }
91
92 1;