aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/Open311/PostServiceRequestUpdates.pm
diff options
context:
space:
mode:
authorMatthew Somerville <matthew@mysociety.org>2020-03-13 15:25:24 +0000
committerMatthew Somerville <matthew@mysociety.org>2020-04-28 18:50:19 +0100
commit96973c1fbecb5db3ba22059f2e4ade2096ec1c04 (patch)
tree818661c903837df06ac9fe8dfe032c95680af52f /perllib/Open311/PostServiceRequestUpdates.pm
parentd3b17d7e96597373a6f1243c5e0f6001d4487588 (diff)
Add sending updates capability to daemon.
Diffstat (limited to 'perllib/Open311/PostServiceRequestUpdates.pm')
-rwxr-xr-xperllib/Open311/PostServiceRequestUpdates.pm113
1 files changed, 67 insertions, 46 deletions
diff --git a/perllib/Open311/PostServiceRequestUpdates.pm b/perllib/Open311/PostServiceRequestUpdates.pm
index 14bebfcb7..fadd063da 100755
--- a/perllib/Open311/PostServiceRequestUpdates.pm
+++ b/perllib/Open311/PostServiceRequestUpdates.pm
@@ -19,17 +19,31 @@ has current_open311 => ( is => 'rw' );
sub send {
my $self = shift;
+ my $bodies = $self->fetch_bodies;
+ foreach my $body (values %$bodies) {
+ $self->construct_open311($body);
+ $self->process_body($body);
+ }
+}
+
+sub fetch_bodies {
my $bodies = FixMyStreet::DB->resultset('Body')->search( {
send_method => SEND_METHOD_OPEN311,
send_comments => 1,
- } );
-
+ }, { prefetch => 'body_areas' } );
+ my %bodies;
while ( my $body = $bodies->next ) {
my $cobrand = $body->get_cobrand_handler;
next if $cobrand && $cobrand->call_hook('open311_post_update_skip');
- $self->current_open311(Open311->new($self->open311_params($body)));
- $self->process_body($body);
+ $bodies{$body->id} = $body;
}
+ return \%bodies;
+}
+
+sub construct_open311 {
+ my ($self, $body) = @_;
+ my $o = Open311->new($self->open311_params($body));
+ $self->current_open311($o);
}
sub open311_params {
@@ -53,41 +67,57 @@ sub open311_params {
sub process_body {
my ($self, $body) = @_;
- my $comments = FixMyStreet::DB->resultset('Comment')->to_body($body)->search( {
- 'me.whensent' => undef,
- 'me.external_id' => undef,
- 'me.state' => 'confirmed',
- 'me.confirmed' => { '!=' => undef },
- 'problem.whensent' => { '!=' => undef },
- 'problem.external_id' => { '!=' => undef },
- 'problem.send_method_used' => { -like => '%Open311%' },
- },
- {
+ my $params = $self->construct_query($self->verbose);
+
+ my $db = FixMyStreet::DB->schema->storage;
+ $db->txn_do(sub {
+ my $comments = FixMyStreet::DB->resultset('Comment')->to_body($body)->search($params, {
+ for => \'UPDATE SKIP LOCKED',
order_by => [ 'confirmed', 'id' ],
- }
- );
+ });
- while ( my $comment = $comments->next ) {
- my $cobrand = $body->get_cobrand_handler || $comment->get_cobrand_logged;
-
- # Some cobrands (e.g. Buckinghamshire) don't want to receive updates
- # from anyone except the original problem reporter.
- if ($cobrand->call_hook(should_skip_sending_update => $comment)) {
- unless (defined $comment->get_extra_metadata('cobrand_skipped_sending')) {
- $comment->set_extra_metadata(cobrand_skipped_sending => 1);
- $comment->update;
- }
- next;
+ while ( my $comment = $comments->next ) {
+ $self->process_update($body, $comment);
}
+ });
+}
- next if !$self->verbose && $comment->send_fail_count && retry_timeout($comment);
-
- $self->process_update($body, $comment, $cobrand);
+sub construct_query {
+ my ($self, $debug) = @_;
+ my $params = {
+ 'me.whensent' => undef,
+ 'me.external_id' => undef,
+ 'me.state' => 'confirmed',
+ 'me.confirmed' => { '!=' => undef },
+ 'me.extra' => [ undef, { -not_like => '%cobrand_skipped_sending%' } ],
+ 'problem.whensent' => { '!=' => undef },
+ 'problem.external_id' => { '!=' => undef },
+ 'problem.send_method_used' => { -like => '%Open311%' },
+ };
+ if (!$debug) {
+ $params->{'-or'} = [
+ 'me.send_fail_count' => 0,
+ 'me.send_fail_timestamp' => { '<', \"current_timestamp - '30 minutes'::interval" },
+ ];
}
+ return $params;
}
sub process_update {
- my ($self, $body, $comment, $cobrand) = @_;
+ my ($self, $body, $comment) = @_;
+
+ my $cobrand = $body->get_cobrand_handler || $comment->get_cobrand_logged;
+
+ # Some cobrands (e.g. Buckinghamshire) don't want to receive updates
+ # from anyone except the original problem reporter.
+ if (my $skip = $cobrand->call_hook(should_skip_sending_update => $comment)) {
+ if ($skip ne 'WAIT' && !defined $comment->get_extra_metadata('cobrand_skipped_sending')) {
+ $comment->set_extra_metadata(cobrand_skipped_sending => 1);
+ $comment->update;
+ }
+ $self->log($comment, 'Skipping');
+ return;
+ }
my $o = $self->current_open311;
@@ -100,30 +130,21 @@ sub process_update {
external_id => $id,
whensent => \'current_timestamp',
} );
+ $self->log($comment, 'Send successful');
} else {
$comment->update( {
send_fail_count => $comment->send_fail_count + 1,
send_fail_timestamp => \'current_timestamp',
send_fail_reason => "Failed to post over Open311\n\n" . $o->error,
} );
-
- if ( $self->verbose && $o->error ) {
- warn $o->error;
- }
+ $self->log($comment, 'Send failed');
}
}
-sub retry_timeout {
- my $row = shift;
-
- my $tz = FixMyStreet->local_time_zone;
- my $now = DateTime->now( time_zone => $tz );
- my $diff = $now - $row->send_fail_timestamp;
- if ( $diff->in_units( 'minutes' ) < 30 ) {
- return 1;
- }
-
- return 0;
+sub log {
+ my ($self, $comment, $msg) = @_;
+ return unless $self->verbose;
+ STDERR->print("[fmsd] [" . $comment->id . "] $msg\n");
}
1;