source: server/trunk/web/lib/Sophie/Base/Async.pm @ 108

Last change on this file since 108 was 108, checked in by nanardon, 14 years ago
  • use a timeout to not overload SQL server
File size: 1.4 KB
Line 
1package Sophie::Base::Async;
2
3use strict;
4use warnings;
5use DBD::Pg qw(:async);
6use Time::HiRes qw(sleep);
7
8sub new {
9    my ($class, $rs, %options) = @_;
10
11    my $query = $options{build}
12        ? $options{build}->($rs)->as_query
13        : $rs->as_query;
14    my ($sql, @bind) = @{ $$query };
15    my $sth = $rs->storage->dbh->prepare(
16        $sql,
17        { pg_async => PG_ASYNC } 
18    ) or return;
19
20    my $time = time;
21    $sth->execute(map { $_->[1] } @bind);
22
23    bless {
24        rs => $rs,
25        sth => $sth,
26        start => $time,
27        timeout => $options{timeout} || 10,
28    }, $class;
29}
30
31sub DESTROY {
32    my ($self) = @_;
33    $self->cancel;
34}
35
36sub cancel {
37    my ($self) = @_;
38    if ($self->{sth}) {
39        $self->{sth}->pg_cancel;
40        $self->{sth} = undef;
41        return 1;
42    } else {
43        return;
44    }
45}
46
47sub result {
48    my ($self) = @_;
49    if (!$self->{sth}) {
50        return;
51    }
52    if ($self->{rs}->storage->dbh->pg_ready) {
53        my $sth = $self->{sth};
54        $self->{sth} = undef;
55        $sth->pg_result;
56        return $sth;
57    } else {
58        return undef;
59    }
60}
61
62sub wait_result {
63    my ($self) = @_;
64
65    while (1) {
66        if (my $res = $self->result) {
67            return $res;
68        }
69        if (time > $self->{start} + $self->{timeout}) {
70            $self->cancel;
71            return;
72        }
73        sleep(0.25);
74    }
75}
76
771;
Note: See TracBrowser for help on using the repository browser.