Skip to content

Commit

Permalink
2.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
remyperona authored Feb 1, 2023
2 parents bcc254b + 1d2e359 commit 46f9df2
Show file tree
Hide file tree
Showing 21 changed files with 232 additions and 66 deletions.
4 changes: 2 additions & 2 deletions imagify.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Imagify
* Plugin URI: https://wordpress.org/plugins/imagify/
* Description: Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool.
* Version: 2.1
* Version: 2.1.1
* Requires at least: 5.3
* Requires PHP: 7.0
* Author: Imagify – Optimize Images & Convert WebP
Expand All @@ -19,7 +19,7 @@
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );

// Imagify defines.
define( 'IMAGIFY_VERSION', '2.1' );
define( 'IMAGIFY_VERSION', '2.1.1' );
define( 'IMAGIFY_SLUG', 'imagify' );
define( 'IMAGIFY_FILE', __FILE__ );
define( 'IMAGIFY_PATH', realpath( plugin_dir_path( IMAGIFY_FILE ) ) . '/' );
Expand Down
14 changes: 7 additions & 7 deletions inc/Dependencies/ActionScheduler/action-scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Description: A robust scheduling library for use in WordPress plugins.
* Author: Automattic
* Author URI: https://automattic.com/
* Version: 3.5.3
* Version: 3.5.4
* License: GPLv3
*
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
Expand All @@ -26,27 +26,27 @@
* @package ActionScheduler
*/

if ( ! function_exists( 'action_scheduler_register_3_dot_5_dot_3' ) && function_exists( 'add_action' ) ) { // WRCS: DEFINED_VERSION.
if ( ! function_exists( 'action_scheduler_register_3_dot_5_dot_4' ) && function_exists( 'add_action' ) ) { // WRCS: DEFINED_VERSION.

if ( ! class_exists( 'ActionScheduler_Versions', false ) ) {
require_once __DIR__ . '/classes/ActionScheduler_Versions.php';
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
}

add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_5_dot_3', 0, 0 ); // WRCS: DEFINED_VERSION.
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_5_dot_4', 0, 0 ); // WRCS: DEFINED_VERSION.

/**
* Registers this version of Action Scheduler.
*/
function action_scheduler_register_3_dot_5_dot_3() { // WRCS: DEFINED_VERSION.
function action_scheduler_register_3_dot_5_dot_4() { // WRCS: DEFINED_VERSION.
$versions = ActionScheduler_Versions::instance();
$versions->register( '3.5.3', 'action_scheduler_initialize_3_dot_5_dot_3' ); // WRCS: DEFINED_VERSION.
$versions->register( '3.5.4', 'action_scheduler_initialize_3_dot_5_dot_4' ); // WRCS: DEFINED_VERSION.
}

/**
* Initializes this version of Action Scheduler.
*/
function action_scheduler_initialize_3_dot_5_dot_3() { // WRCS: DEFINED_VERSION.
function action_scheduler_initialize_3_dot_5_dot_4() { // WRCS: DEFINED_VERSION.
// A final safety check is required even here, because historic versions of Action Scheduler
// followed a different pattern (in some unusual cases, we could reach this point and the
// ActionScheduler class is already defined—so we need to guard against that).
Expand All @@ -58,7 +58,7 @@ function action_scheduler_initialize_3_dot_5_dot_3() { // WRCS: DEFINED_VERSION.

// Support usage in themes - load this version if no plugin has loaded a version yet.
if ( did_action( 'plugins_loaded' ) && ! doing_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler', false ) ) {
action_scheduler_initialize_3_dot_5_dot_3(); // WRCS: DEFINED_VERSION.
action_scheduler_initialize_3_dot_5_dot_4(); // WRCS: DEFINED_VERSION.
do_action( 'action_scheduler_pre_theme_init' );
ActionScheduler_Versions::initialize_latest_version();
}
Expand Down
10 changes: 10 additions & 0 deletions inc/Dependencies/ActionScheduler/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
*** Changelog ***

= 3.5.4 - 2023-01-17 =
* Add pre filters during action registration.
* Async scheduling.
* Calculate timeouts based on total actions.
* Correctly order the parameters for `ActionScheduler_ActionFactory`'s calls to `single_unique`.
* Fetch action in memory first before releasing claim to avoid deadlock.
* PHP 8.2: declare property to fix creation of dynamic property warning.
* PHP 8.2: fix "Using ${var} in strings is deprecated, use {$var} instead".
* Prevent `undefined variable` warning for `$num_pastdue_actions`.

= 3.5.3 - 2022-11-09 =
* Query actions with partial match.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,9 @@ public function get_stored_action( $status, $hook, array $args = array(), Action
/**
* Enqueue an action to run one time, as soon as possible (rather a specific scheduled time).
*
* This method creates a new action with the NULLSchedule. This schedule maps to a MySQL datetime string of
* 0000-00-00 00:00:00. This is done to create a psuedo "async action" type that is fully backward compatible.
* Existing queries to claim actions claim by date, meaning actions scheduled for 0000-00-00 00:00:00 will
* always be claimed prior to actions scheduled for a specific date. This makes sure that any async action is
* given priority in queue processing. This has the added advantage of making sure async actions can be
* claimed by both the existing WP Cron and WP CLI runners, as well as a new async request runner.
* This method creates a new action using the NullSchedule. In practice, this results in an action scheduled to
* execute "now". Therefore, it will generally run as soon as possible but is not prioritized ahead of other actions
* that are already past-due.
*
* @param string $hook The hook to trigger when this action runs.
* @param array $args Args to pass when the hook is triggered.
Expand Down Expand Up @@ -146,7 +143,7 @@ public function recurring( $hook, $args = array(), $first = null, $interval = nu
*/
public function recurring_unique( $hook, $args = array(), $first = null, $interval = null, $group = '', $unique = true ) {
if ( empty( $interval ) ) {
return $this->single_unique( $hook, $unique, $args, $first, $group );
return $this->single_unique( $hook, $args, $first, $group, $unique );
}
$date = as_get_datetime_object( $first );
$schedule = new ActionScheduler_IntervalSchedule( $date, $interval );
Expand Down Expand Up @@ -188,7 +185,7 @@ public function cron( $hook, $args = array(), $base_timestamp = null, $schedule
**/
public function cron_unique( $hook, $args = array(), $base_timestamp = null, $schedule = null, $group = '', $unique = true ) {
if ( empty( $schedule ) ) {
return $this->single_unique( $hook, $unique, $args, $base_timestamp, $group );
return $this->single_unique( $hook, $args, $base_timestamp, $group, $unique );
}
$date = as_get_datetime_object( $base_timestamp );
$cron = CronExpression::factory( $schedule );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,17 @@ protected function check_pastdue_actions() {
$threshold_seconds = ( int ) apply_filters( 'action_scheduler_pastdue_actions_seconds', DAY_IN_SECONDS );
$threshhold_min = ( int ) apply_filters( 'action_scheduler_pastdue_actions_min', 1 );

# Allow third-parties to preempt the default check logic.
// Set fallback value for past-due actions count.
$num_pastdue_actions = 0;

// Allow third-parties to preempt the default check logic.
$check = apply_filters( 'action_scheduler_pastdue_actions_check_pre', null );

// If no third-party preempted and there are no past-due actions, return early.
if ( ! is_null( $check ) ) {
return;
}

# Scheduled actions query arguments.
$query_args = array(
'date' => as_get_datetime_object( time() - $threshold_seconds ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
/** @var ActionScheduler_QueueRunner */
private static $runner = null;

/** @var int */
private $processed_actions_count = 0;

/**
* @return ActionScheduler_QueueRunner
* @codeCoverageIgnore
Expand Down Expand Up @@ -125,17 +128,18 @@ public function run( $context = 'WP Cron' ) {
ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() );
do_action( 'action_scheduler_before_process_queue' );
$this->run_cleanup();
$processed_actions = 0;

$this->processed_actions_count = 0;
if ( false === $this->has_maximum_concurrent_batches() ) {
$batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 );
do {
$processed_actions_in_batch = $this->do_batch( $batch_size, $context );
$processed_actions += $processed_actions_in_batch;
} while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $processed_actions ) ); // keep going until we run out of actions, time, or memory
$processed_actions_in_batch = $this->do_batch( $batch_size, $context );
$this->processed_actions_count += $processed_actions_in_batch;
} while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $this->processed_actions_count ) ); // keep going until we run out of actions, time, or memory
}

do_action( 'action_scheduler_after_process_queue' );
return $processed_actions;
return $this->processed_actions_count;
}

/**
Expand All @@ -162,7 +166,7 @@ protected function do_batch( $size = 100, $context = '' ) {
$this->process_action( $action_id, $context );
$processed_actions++;

if ( $this->batch_limits_exceeded( $processed_actions ) ) {
if ( $this->batch_limits_exceeded( $processed_actions + $this->processed_actions_count ) ) {
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,14 @@ protected function get_execution_time() {
* @return bool
*/
protected function time_likely_to_be_exceeded( $processed_actions ) {
$execution_time = $this->get_execution_time();
$max_execution_time = $this->get_time_limit();

// Safety against division by zero errors.
if ( 0 === $processed_actions ) {
return $execution_time >= $max_execution_time;
}

$execution_time = $this->get_execution_time();
$max_execution_time = $this->get_time_limit();
$time_per_action = $execution_time / $processed_actions;
$estimated_time = $execution_time + ( $time_per_action * 3 );
$likely_to_be_exceeded = $estimated_time > $max_execution_time;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ protected function validate_sql_comparator( $comparison_operator ) {
protected function get_scheduled_date_string( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
$next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date;
if ( ! $next ) {
return '0000-00-00 00:00:00';
$next = date_create();
}
$next->setTimezone( new DateTimeZone( 'UTC' ) );

Expand All @@ -274,7 +274,7 @@ protected function get_scheduled_date_string( ActionScheduler_Action $action, Da
protected function get_scheduled_date_string_local( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
$next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date;
if ( ! $next ) {
return '0000-00-00 00:00:00';
$next = date_create();
}

ActionScheduler_TimezoneHelper::set_local_timezone( $next );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -935,8 +935,31 @@ public function find_actions_by_claim_id( $claim_id ) {
public function release_claim( ActionScheduler_ActionClaim $claim ) {
/** @var \wpdb $wpdb */
global $wpdb;
$wpdb->update( $wpdb->actionscheduler_actions, array( 'claim_id' => 0 ), array( 'claim_id' => $claim->get_id() ), array( '%d' ), array( '%d' ) );
/**
* Deadlock warning: This function modifies actions to release them from claims that have been processed. Earlier, we used to it in a atomic query, i.e. we would update all actions belonging to a particular claim_id with claim_id = 0.
* While this was functionally correct, it would cause deadlock, since this update query will hold a lock on the claim_id_.. index on the action table.
* This allowed the possibility of a race condition, where the claimer query is also running at the same time, then the claimer query will also try to acquire a lock on the claim_id_.. index, and in this case if claim release query has already progressed to the point of acquiring the lock, but have not updated yet, it would cause a deadlock.
*
* We resolve this by getting all the actions_id that we want to release claim from in a separate query, and then releasing the claim on each of them. This way, our lock is acquired on the action_id index instead of the claim_id index. Note that the lock on claim_id will still be acquired, but it will only when we actually make the update, rather than when we select the actions.
*/
$action_ids = $wpdb->get_col( $wpdb->prepare( "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id = %d", $claim->get_id() ) );

$row_updates = 0;
if ( count( $action_ids ) > 0 ) {
$action_id_string = implode( ',', array_map( 'absint', $action_ids ) );
$row_updates = $wpdb->query( "UPDATE {$wpdb->actionscheduler_actions} SET claim_id = 0 WHERE action_id IN ({$action_id_string})" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
}

$wpdb->delete( $wpdb->actionscheduler_claims, array( 'claim_id' => $claim->get_id() ), array( '%d' ) );

if ( $row_updates < count( $action_ids ) ) {
throw new RuntimeException(
sprintf(
__( 'Unable to release actions from claim id %d.', 'woocommerce' ),
$claim->get_id()
)
);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
*/
class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule {

/** @var DateTime|null */
protected $scheduled_date;

/**
* Make the $date param optional and default to null.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ protected function get_table_definition( $table ) {
action_id bigint(20) unsigned NOT NULL auto_increment,
hook varchar(191) NOT NULL,
status varchar(20) NOT NULL,
scheduled_date_gmt datetime NULL default '${default_date}',
scheduled_date_local datetime NULL default '${default_date}',
scheduled_date_gmt datetime NULL default '{$default_date}',
scheduled_date_local datetime NULL default '{$default_date}',
args varchar($max_index_length),
schedule longtext,
group_id bigint(20) unsigned NOT NULL default '0',
attempts int(11) NOT NULL default '0',
last_attempt_gmt datetime NULL default '${default_date}',
last_attempt_local datetime NULL default '${default_date}',
last_attempt_gmt datetime NULL default '{$default_date}',
last_attempt_local datetime NULL default '{$default_date}',
claim_id bigint(20) unsigned NOT NULL default '0',
extended_args varchar(8000) DEFAULT NULL,
PRIMARY KEY (action_id),
Expand All @@ -71,7 +71,7 @@ protected function get_table_definition( $table ) {

return "CREATE TABLE {$table_name} (
claim_id bigint(20) unsigned NOT NULL auto_increment,
date_created_gmt datetime NULL default '${default_date}',
date_created_gmt datetime NULL default '{$default_date}',
PRIMARY KEY (claim_id),
KEY date_created_gmt (date_created_gmt)
) $charset_collate";
Expand Down Expand Up @@ -111,16 +111,16 @@ public function update_schema_5_0( $table, $db_version ) {

// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$table_name = $wpdb->prefix . 'actionscheduler_actions';
$table_list = $wpdb->get_col( "SHOW TABLES LIKE '${table_name}'" );
$table_list = $wpdb->get_col( "SHOW TABLES LIKE '{$table_name}'" );
$default_date = self::DEFAULT_DATE;

if ( ! empty( $table_list ) ) {
$query = "
ALTER TABLE ${table_name}
MODIFY COLUMN scheduled_date_gmt datetime NULL default '${default_date}',
MODIFY COLUMN scheduled_date_local datetime NULL default '${default_date}',
MODIFY COLUMN last_attempt_gmt datetime NULL default '${default_date}',
MODIFY COLUMN last_attempt_local datetime NULL default '${default_date}'
ALTER TABLE {$table_name}
MODIFY COLUMN scheduled_date_gmt datetime NULL default '{$default_date}',
MODIFY COLUMN scheduled_date_local datetime NULL default '{$default_date}',
MODIFY COLUMN last_attempt_gmt datetime NULL default '{$default_date}',
MODIFY COLUMN last_attempt_local datetime NULL default '{$default_date}'
";
$wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
}
Expand Down
Loading

0 comments on commit 46f9df2

Please sign in to comment.