# $Id$
# -*-perl-*-

use strict;
use warnings;

require './t/lib/db-common.pl';

use TheSchwartz;
use Test::More tests => 2;

# how we keep track of if job was done twice:  signal from children back up to us
my $work_count = 0;
$SIG{USR1} = sub {
    $work_count++;
};

# force the race condition to happen
{
    no warnings 'once';
    $TheSchwartz::T_AFTER_GRAB_SELECT_BEFORE_UPDATE = sub {
        select undef, undef, undef, 1.5;
    };
}

# kill children on exit
my %children;    # pid -> 1

END {
    my @pids = keys %children;
    kill -9, @pids if @pids;
}

run_tests_innodb(
    2,
    sub {

        # get one job into database, to see if children do it twice:
        {
            my $client = test_client( dbs => ['ts1'] );
            my $handle = $client->insert( "Worker::Addition",
                { numbers => [ 1, 2 ] } );
            isa_ok $handle, 'TheSchwartz::JobHandle', "inserted job";
        }

        # two children to race to get the above job.
        work();
        work();

        # hang out for 3 seconds waiting for children to init/race/finish
        my $now = time();
        while ( time() < $now + 3 ) {
            sleep 1;
        }

        is( $work_count, 1, "only got one signal from worker children" );
        teardown_dbs('ts1');
    }
);

sub work {

    # parent:
    if ( my $childpid = fork() ) {
        $children{$childpid} = 1;
        return;
    }

    my $client = test_client(
        dbs  => ['ts1'],
        init => 0
    );

    # child:
    my $job = Worker::Addition->grab_job($client);
    if ($job) {
        eval { Worker::Addition->work($job); };
    }
    exit 0;
}

############################################################################
package Worker::Addition;
use base 'TheSchwartz::Worker';

sub work {
    my ( $class, $job ) = @_;
    kill 'USR1', getppid();
    $job->completed;
}

# tell framework to set 'grabbed_until' to time() + 60.  because if
# we can't  add some numbers in 30 seconds, our process probably
# failed and work should be reassigned.
sub grab_for {30}