verdict(); $failures = $is_failure ? $link->failures + 1 : 0; $verdict = $this->stored_verdict( $judgement, $failures ); $is_same_verdict = $verdict === $link->verdict; return new CheckRecord( verdict: $verdict, reason: $judgement->reason, http_code: $judgement->http_code, final_url: $judgement->final_url, streak: $is_same_verdict ? $link->streak + 1 : self::FIRST_STREAK, failures: $failures, since: $is_same_verdict ? ( $link->since ?? $now ) : $now, checked_at: $now, check_after: $now + $this->delay_before_next_check( $verdict, $judgement->reason, $failures ) ); } private function stored_verdict( Judgement $judgement, int $failures ): Verdict { $verdict = $judgement->verdict(); if ( Verdict::Broken !== $verdict ) { return $verdict; } return $this->is_confirmed( $judgement->reason, $failures ) ? Verdict::Broken : Verdict::Retrying; } private function is_confirmed( Reason $reason, int $failures ): bool { return match ( $reason ) { Reason::Trashed => true, Reason::NotFound, Reason::Gone => $failures >= self::MISSING_PAGE_CONFIRMING_FAILURES, Reason::NoHost => $failures >= self::NO_HOST_CONFIRMING_FAILURES, default => $failures > self::TEMPORARY_RETRY_COUNT, }; } private function delay_before_next_check( Verdict $verdict, Reason $reason, int $failures ): int { if ( Verdict::Retrying !== $verdict ) { return self::SETTLED_RECHECK_DELAY; } return match ( $reason ) { Reason::NotFound, Reason::Gone => self::MISSING_PAGE_CONFIRMATION_DELAY, Reason::NoHost => self::NO_HOST_RETRY_DELAY, default => $this->temporary_retry_delay( $failures ), }; } private function temporary_retry_delay( int $failures ): int { return match ( $failures ) { 1 => self::FIRST_TEMPORARY_RETRY_DELAY, 2 => self::SECOND_TEMPORARY_RETRY_DELAY, default => self::LAST_TEMPORARY_RETRY_DELAY, }; } }