Automattic\WooCommerce\Internal\ProductFeed\Integrations\POSCatalog
AsyncGenerator::validate_status
Validates the status of the feed generation.
Makes sure that the file exists for completed jobs, that scheduled jobs are not stuck, etc.
Method of the class: AsyncGenerator{}
Hooks from the method
Returns
true|false. True if the status is valid, false otherwise.
Usage
// private - for code of main (parent) class only $result = $this->validate_status( $status ): bool;
- $status(array) (required)
- The status of the feed generation.
AsyncGenerator::validate_status() AsyncGenerator::validate status code WC 11.0.0
private function validate_status( array $status ): bool {
// A failed job is never served as-is. get_status() surfaces the failure to the client once and
// then clears it, so the client can react and its next poll starts a fresh run; force_regeneration()
// likewise treats it as invalid and regenerates. Either way it must not validate.
if ( self::STATE_FAILED === $status['state'] ) {
return false;
}
// For completed jobs, the file must still exist and not be expired (e.g. manually deleted, or a
// cleanup job that failed to clear an expired feed).
if ( self::STATE_COMPLETED === $status['state'] ) {
if ( ! file_exists( $status['path'] ) ) {
return false;
}
if ( ! isset( $status['completed_at'] ) ) {
return false;
}
if ( $status['completed_at'] + self::FEED_EXPIRY < time() ) {
return false;
}
}
/**
* Allows the timeout for a feed to remain in `scheduled` state to be changed. Past this point
* Action Scheduler is typically stuck and the job is regenerated.
*
* @param int $stuck_time The stuck time in seconds.
* @return int The stuck time in seconds.
* @since 10.5.0
*/
$scheduled_timeout = apply_filters( 'woocommerce_product_feed_scheduled_timeout', 10 * MINUTE_IN_SECONDS );
if (
self::STATE_SCHEDULED === $status['state']
&& (
! isset( $status['scheduled_at'] )
|| time() - $status['scheduled_at'] > $scheduled_timeout
)
) {
return false;
}
// An in-progress job that has not refreshed its heartbeat (`updated_at`, set on start and after
// every batch) within the timeout was most likely killed (host timeout or out of memory) before
// it could mark itself failed. Treat it as stuck so a new feed can be generated.
if ( self::STATE_IN_PROGRESS === $status['state'] ) {
$last_activity = $status['updated_at'] ?? $status['scheduled_at'] ?? 0;
/**
* Allows the heartbeat timeout for an `in_progress` feed to be changed. Past this point the
* job is treated as stuck and regenerated.
*
* The default is kept comfortably larger than the per-batch time budget on purpose. The
* heartbeat only refreshes between batches, so the longest gap a healthy job can produce is
* roughly one batch (`woocommerce_product_feed_batch_time_limit`). A timeout at or near that
* budget would let a single slow-but-valid batch look stuck, and recovery would then discard
* the partial the live process is still writing. Deriving it as a multiple (with a floor)
* keeps that margin even when the batch budget is raised via its own filter.
*
* @param int $stuck_time The stuck time in seconds.
* @return int The stuck time in seconds.
* @since 11.0.0
*/
$in_progress_timeout = apply_filters(
'woocommerce_product_feed_in_progress_timeout',
max( 15 * MINUTE_IN_SECONDS, 3 * $this->get_batch_time_limit() )
);
if ( time() - $last_activity > $in_progress_timeout ) {
return false;
}
}
return true;
}