From d1b3fa2be8494d0466ac5719357d4dc1b0251268 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Mon, 1 Jun 2026 09:40:20 +0200 Subject: [PATCH 01/11] add 'state' column to the database --- lib/Zonemaster/Backend/DB/MySQL.pm | 4 +++- lib/Zonemaster/Backend/DB/PostgreSQL.pm | 4 +++- lib/Zonemaster/Backend/DB/SQLite.pm | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/Zonemaster/Backend/DB/MySQL.pm b/lib/Zonemaster/Backend/DB/MySQL.pm index 86ec1d7df..886f60e56 100644 --- a/lib/Zonemaster/Backend/DB/MySQL.pm +++ b/lib/Zonemaster/Backend/DB/MySQL.pm @@ -73,12 +73,14 @@ sub create_schema { priority integer DEFAULT 10, queue integer DEFAULT 0, progress integer DEFAULT 0, + state VARCHAR(20) NOT NULL DEFAULT "waiting", fingerprint character varying(32), params blob NOT NULL, results mediumblob DEFAULT NULL, undelegated integer NOT NULL DEFAULT 0, - UNIQUE (hash_id) + UNIQUE (hash_id), + CHECK (state IN ("waiting", "running", "completed", "cancelled", "crashed")) ) ENGINE=InnoDB ' ) or die Zonemaster::Backend::Error::Internal->new( reason => "MySQL error, could not create 'test_results' table", data => $dbh->errstr() ); diff --git a/lib/Zonemaster/Backend/DB/PostgreSQL.pm b/lib/Zonemaster/Backend/DB/PostgreSQL.pm index 617d12abc..3998ce8c1 100644 --- a/lib/Zonemaster/Backend/DB/PostgreSQL.pm +++ b/lib/Zonemaster/Backend/DB/PostgreSQL.pm @@ -70,12 +70,14 @@ sub create_schema { priority integer DEFAULT 10, queue integer DEFAULT 0, progress integer DEFAULT 0, + state VARCHAR(20) NOT NULL DEFAULT "waiting", fingerprint varchar(32), params json NOT NULL, undelegated integer NOT NULL DEFAULT 0, results json, - UNIQUE (hash_id) + UNIQUE (hash_id), + CHECK (state IN ("waiting", "running", "completed", "cancelled", "crashed")) ) ' ) or die Zonemaster::Backend::Error::Internal->new( reason => "PostgreSQL error, could not create 'test_results' table", data => $dbh->errstr() ); diff --git a/lib/Zonemaster/Backend/DB/SQLite.pm b/lib/Zonemaster/Backend/DB/SQLite.pm index e04108f89..1032051b9 100644 --- a/lib/Zonemaster/Backend/DB/SQLite.pm +++ b/lib/Zonemaster/Backend/DB/SQLite.pm @@ -73,12 +73,14 @@ sub create_schema { priority integer DEFAULT 10, queue integer DEFAULT 0, progress integer DEFAULT 0, + state VARCHAR(20) NOT NULL DEFAULT "waiting", fingerprint character varying(32), params text NOT NULL, results text DEFAULT NULL, undelegated boolean NOT NULL DEFAULT false, - UNIQUE (hash_id) + UNIQUE (hash_id), + CHECK (state IN ("waiting", "running", "completed", "cancelled", "crashed")) ) ' ) or die Zonemaster::Backend::Error::Internal->new( reason => "SQLite error, could not create 'test_results' table", data => $dbh->errstr() ); From 5fa5a08f49a98f5fd437556012013d1a0f379b23 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Mon, 1 Jun 2026 10:50:37 +0200 Subject: [PATCH 02/11] update state constants --- lib/Zonemaster/Backend/DB.pm | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index b83b6469f..b35ad3c53 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -60,7 +60,7 @@ The test is waiting to be processed. =cut -Readonly our $TEST_WAITING => 'WAITING'; +Readonly our $TEST_WAITING => 'waiting'; =head2 $TEST_RUNNING @@ -68,38 +68,39 @@ The test is currently being processed. =cut -Readonly our $TEST_RUNNING => 'RUNNING'; +Readonly our $TEST_RUNNING => 'running'; =head2 $TEST_COMPLETED The test was already processed. -This state encompasses all of the following: +=cut -=over 2 +Readonly our $TEST_COMPLETED => 'completed'; -=item +=head2 $TEST_CANCELLED -The Zonemaster Engine test terminated normally. - -=item +The test was cancelled. -A critical error occurred while processing. +=cut -=item +Readonly our $TEST_CANCELLED => 'cancelled'; -The processing was cancelled because it took too long. +=head2 $TEST_CRASHED -=back +The test crashed. =cut -Readonly our $TEST_COMPLETED => 'COMPLETED'; +Readonly our $TEST_CRASHED => 'crashed'; + our @EXPORT_OK = qw( $TEST_WAITING $TEST_RUNNING $TEST_COMPLETED + $TEST_CANCELLED + $TEST_CRASHED ); From 8b968756c787f1cfc0f63075105410cd04ad0341 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 08:51:27 +0200 Subject: [PATCH 03/11] change test_state() --- lib/Zonemaster/Backend/DB.pm | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index b35ad3c53..f8afea352 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -347,31 +347,21 @@ sub test_progress { sub test_state { my ( $self, $test_id ) = @_; - my ( $progress ) = $self->dbh->selectrow_array( + my ( $state ) = $self->dbh->selectrow_array( q[ - SELECT progress + SELECT state FROM test_results WHERE hash_id = ? ], undef, $test_id, ); - if ( !defined $progress ) { + + if ( !defined $state ) { die Zonemaster::Backend::Error::Internal->new( reason => 'job not found' ); } - if ( $progress == 0 ) { - return $TEST_WAITING; - } - elsif ( 0 < $progress && $progress < 100 ) { - return $TEST_RUNNING; - } - elsif ( $progress == 100 ) { - return $TEST_COMPLETED; - } - else { - die Zonemaster::Backend::Error::Internal->new( reason => 'state could not be determined' ); - } + return $state; } sub set_test_completed { From 2d4876080b0dc7113b95b3e26e249f69c06bc349 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:12:57 +0200 Subject: [PATCH 04/11] change create_new_test() --- lib/Zonemaster/Backend/DB.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index f8afea352..c6d2fe58e 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -218,11 +218,12 @@ sub create_new_test { created_at, priority, queue, + state, fingerprint, params, domain, undelegated - ) VALUES (?,?,?,?,?,?,?,?,?) + ) VALUES (?,?,?,?,?,?,?,?,?,?) ], undef, $hash_id, @@ -230,6 +231,7 @@ sub create_new_test { $self->format_time( time() ), $priority, $queue_label, + $TEST_WAITING, $fingerprint, $encoded_params, encode_utf8( $test_params->{domain} ), From b4c260903a353af88717d7014cf827c65fb1a9f9 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:16:22 +0200 Subject: [PATCH 05/11] change claim_test() --- lib/Zonemaster/Backend/DB.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index c6d2fe58e..a3f1056da 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -693,13 +693,16 @@ sub claim_test { q[ UPDATE test_results SET progress = 1, + state = ?, started_at = ? WHERE hash_id = ? - AND progress = 0 + AND state = ? ], undef, + $TEST_RUNNING, $self->format_time( time() ), $test_id, + $TEST_WAITING, ); return $rows_affected == 1; From 6fb39b949bc714b02dae8b1337a9d6be484af190 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:23:09 +0200 Subject: [PATCH 06/11] change set_test_completed() --- lib/Zonemaster/Backend/DB.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index a3f1056da..23170e181 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -379,12 +379,14 @@ sub set_test_completed { q[ UPDATE test_results SET progress = 100, + state = ?, ended_at = ? WHERE hash_id = ? AND 0 < progress AND progress < 100 ], undef, + $TEST_COMPLETED, $self->format_time( time() ), $test_id, ); From 98a344b10f1d354f43054f144ab397702e01aac3 Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:26:16 +0200 Subject: [PATCH 07/11] change store_results() --- lib/Zonemaster/Backend/DB.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index 23170e181..eef1f18bc 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -431,16 +431,18 @@ sub store_results { q[ UPDATE test_results SET progress = 100, + state = ?, ended_at = ?, results = ? WHERE hash_id = ? - AND 0 < progress - AND progress < 100 + AND state = ? ], undef, + $TEST_COMPLETED, $self->format_time( time() ), $new_results, $test_id, + $TEST_RUNNING, ); if ( $rows_affected == 0 ) { From e2743946f48f32ae366d60deb9ad2ac576c0713e Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:36:47 +0200 Subject: [PATCH 08/11] handle test canceled and crashed --- lib/Zonemaster/Backend/DB.pm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index eef1f18bc..a4a71df0d 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -367,7 +367,9 @@ sub test_state { } sub set_test_completed { - my ( $self, $test_id ) = @_; + my ( $self, $test_id, $state) = @_; + + $state //= $TEST_COMPLETED; my $current_state = $self->test_state( $test_id ); @@ -386,7 +388,7 @@ sub set_test_completed { AND progress < 100 ], undef, - $TEST_COMPLETED, + $state, $self->format_time( time() ), $test_id, ); @@ -813,7 +815,7 @@ sub process_unfinished_tests { } ); while ( my $h = $sth1->fetchrow_hashref ) { - $self->force_end_test($h->{hash_id}, $msg); + $self->force_end_test($h->{hash_id}, $msg, $TEST_CANCELLED); } } @@ -863,10 +865,10 @@ and mark test with $hash_id as COMPLETED. =cut sub force_end_test { - my ( $self, $hash_id, $msg ) = @_; + my ( $self, $hash_id, $msg ,$state) = @_; $self->add_result_entries( $hash_id, $msg ); - $self->set_test_completed( $hash_id ); + $self->set_test_completed( $hash_id, $state); } =head2 process_dead_test($hash_id) @@ -888,7 +890,7 @@ sub process_dead_test { timestamp => $self->get_relative_start_time($hash_id) } ); - $self->force_end_test($hash_id, $msg); + $self->force_end_test($hash_id, $msg, $TEST_CRASHED); } # Converts the domain to lowercase and if the domain is not the root ('.') From 0517a630a70b0e5e84e77b5eaa8320f2943b490f Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:40:11 +0200 Subject: [PATCH 09/11] change get_test_request() --- lib/Zonemaster/Backend/DB.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index a4a71df0d..5530ee87f 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -640,13 +640,14 @@ sub get_test_request { SELECT hash_id, batch_id FROM test_results - WHERE progress = 0 + WHERE state = ? AND queue = ? ORDER BY priority DESC, id ASC LIMIT 1 ], undef, + $TEST_WAITING, $queue_label, ); } @@ -656,11 +657,13 @@ sub get_test_request { SELECT hash_id, batch_id FROM test_results - WHERE progress = 0 + WHERE state = ? ORDER BY priority DESC, id ASC LIMIT 1 ], + undef, + $TEST_WAITING, ); } From 7ec09760c71ec95a3facb091dac194c11f927a2e Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:42:20 +0200 Subject: [PATCH 10/11] change select_unfinished_tests() --- lib/Zonemaster/Backend/DB.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index 5530ee87f..70b924673 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -837,11 +837,11 @@ sub select_unfinished_tests { SELECT hash_id, results FROM test_results WHERE started_at < ? - AND progress > 0 - AND progress < 100 + AND state = ? AND queue = ?" ); $sth->execute( # $self->format_time( time() - $test_run_timeout ), + $TEST_RUNNING, $queue_label, ); return $sth; @@ -851,10 +851,10 @@ sub select_unfinished_tests { SELECT hash_id, results FROM test_results WHERE started_at < ? - AND progress > 0 - AND progress < 100" ); + AND state = ?" ); $sth->execute( # $self->format_time( time() - $test_run_timeout ), + $TEST_RUNNING, ); return $sth; } From ab41bad209682df6ae2629efc673f5f183cc112d Mon Sep 17 00:00:00 2001 From: Michael Timbert Date: Tue, 2 Jun 2026 09:48:02 +0200 Subject: [PATCH 11/11] change test_progress() --- lib/Zonemaster/Backend/DB.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm index 70b924673..d949350fe 100644 --- a/lib/Zonemaster/Backend/DB.pm +++ b/lib/Zonemaster/Backend/DB.pm @@ -315,12 +315,13 @@ sub test_progress { UPDATE test_results SET progress = ? WHERE hash_id = ? - AND 1 <= progress + AND state = ? AND progress <= ? ], undef, $progress, $test_id, + $TEST_RUNNING, $progress, ); if ( $rows_affected == 0 ) {