Subject: | Future lost and failed registers not propogated if primary node register fails |
Paul,
Second in my series on "how not to provide patches", I've been harbouring this since our discussion earlier this week.
Again, it's quite hard to test for, but I found this specifically happens when a badly formatted CQL request is sent.
You get a lost sequence future, and an error.
The patch provided is the variation which errs on the side of caution.
If you can help me work out how to get it tested, I'm happy to.
Thanks
Gareth
Subject: | Net-Async-CassandraCQL-0.11-eventwatch.patch |
diff -Naurb ../Net-Async-CassandraCQL-0.11.orig/lib/Net/Async/CassandraCQL.pm ./lib/Net/Async/CassandraCQL.pm
--- ../Net-Async-CassandraCQL-0.11.orig/lib/Net/Async/CassandraCQL.pm 2015-01-24 09:43:27.919671085 +0000
+++ ./lib/Net/Async/CassandraCQL.pm 2015-01-25 13:29:00.190691508 +0000
@@ -510,28 +510,33 @@
{
my $self = shift;
- my @primaries = keys %{ $self->{primary_ids} };
+ # Only the primaries which haven't been watched already
+ my @primaries = grep { !$self->{event_ids}{ $_ } } keys %{ $self->{primary_ids} };
- {
- my $nodeid = $primaries[rand @primaries];
- redo if $self->{event_ids}{$nodeid};
+ # If there aren't any futues left to try, don't create an infinite loop
+ # Don't expect this to happen, but just in case
+ return Future->fail('No primary node available to eventwatch') unless @primaries;
+
+ my $nodeid = $primaries[int rand @primaries];
$self->{event_ids}{$nodeid} = 1;
- my $node = $self->{nodes}{$nodeid};
- $node->{ready_f}->on_done( sub {
+ my $node = $self->{nodes}{$nodeid} or die "Expected node: '$nodeid' to exist";
+
+ return $node->{ready_f} = $node->{ready_f}->then( sub {
my $conn = shift;
$conn->configure(
on_topology_change => $self->{on_topology_change_cb},
on_status_change => $self->{on_status_change_cb},
);
$conn->register( [qw( TOPOLOGY_CHANGE STATUS_CHANGE )] )
- ->on_fail( sub {
+ ->then_done( $conn )
+ ->else( sub {
delete $self->{event_ids}{$nodeid};
- $self->_pick_new_eventwatch
+ # Return the new attempt to eventwatch a differnt primary
+ return $self->_pick_new_eventwatch;
+ })
});
- });
- }
}
sub _on_topology_change