Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
WP Plugins
Cron-Control
Commits
fe427ade
Commit
fe427ade
authored
May 16, 2017
by
Erick Hitter
Committed by
GitHub
May 16, 2017
Browse files
Merge pull request #108 from Automattic/106/allow-many-cron
Allow whitelisted events to run concurrently
parents
024c45b1
37ec9340
Changes
1
Hide whitespace changes
Inline
Side-by-side
includes/class-events.php
View file @
fe427ade
...
...
@@ -12,6 +12,8 @@ class Events extends Singleton {
*/
const
LOCK
=
'run-events'
;
private
$concurrent_action_whitelist
=
array
();
/**
* Register hooks
*/
...
...
@@ -22,6 +24,9 @@ class Events extends Singleton {
// Prepare environment as early as possible
$earliest_action
=
did_action
(
'muplugins_loaded'
)
?
'plugins_loaded'
:
'muplugins_loaded'
;
add_action
(
$earliest_action
,
array
(
$this
,
'prepare_environment'
)
);
// Allow code loaded as late as the theme to modify the whitelist
add_action
(
'after_setup_theme'
,
array
(
$this
,
'populate_concurrent_action_whitelist'
)
);
}
/**
...
...
@@ -47,6 +52,20 @@ class Events extends Singleton {
}
}
/**
* Allow certain events to be run concurrently
*
* By default, multiple events of the same action cannot be run concurrently, due to alloptions and other data-corruption issues
* Some events, however, are fine to run concurrently, and should be whitelisted for such
*/
public
function
populate_concurrent_action_whitelist
()
{
$concurrency_whitelist
=
apply_filters
(
'a8c_cron_control_concurrent_event_whitelist'
,
array
()
);
if
(
is_array
(
$concurrency_whitelist
)
&&
!
empty
(
$concurrency_whitelist
)
)
{
$this
->
concurrent_action_whitelist
=
$concurrency_whitelist
;
}
}
/**
* List events pending for the current period
*/
...
...
@@ -281,8 +300,15 @@ class Events extends Singleton {
* @return bool
*/
private
function
can_run_event
(
$event
)
{
// Limit to one concurrent execution of a specific action
if
(
!
Lock
::
check_lock
(
$this
->
get_lock_key_for_event_action
(
$event
),
1
,
JOB_LOCK_EXPIRY_IN_MINUTES
*
\
MINUTE_IN_SECONDS
)
)
{
// Limit to one concurrent execution of a specific action by default
$limit
=
1
;
if
(
isset
(
$this
->
concurrent_action_whitelist
[
$event
->
action
]
)
)
{
$limit
=
absint
(
$this
->
concurrent_action_whitelist
[
$event
->
action
]
);
$limit
=
min
(
$limit
,
JOB_CONCURRENCY_LIMIT
);
}
if
(
!
Lock
::
check_lock
(
$this
->
get_lock_key_for_event_action
(
$event
),
$limit
,
JOB_LOCK_EXPIRY_IN_MINUTES
*
\
MINUTE_IN_SECONDS
)
)
{
return
false
;
}
...
...
@@ -292,7 +318,7 @@ class Events extends Singleton {
}
// Check if any resources are available to execute this job
// If not, the indivdual-event lock must be freed, otherwise it's deadlocked until it times out
// If not, the indiv
i
dual-event lock must be freed, otherwise it's deadlocked until it times out
if
(
!
Lock
::
check_lock
(
self
::
LOCK
,
JOB_CONCURRENCY_LIMIT
)
)
{
$this
->
reset_event_lock
(
$event
);
return
false
;
...
...
@@ -325,7 +351,14 @@ class Events extends Singleton {
* @return bool
*/
private
function
reset_event_lock
(
$event
)
{
return
Lock
::
reset_lock
(
$this
->
get_lock_key_for_event_action
(
$event
),
JOB_LOCK_EXPIRY_IN_MINUTES
*
\
MINUTE_IN_SECONDS
);
$lock_key
=
$this
->
get_lock_key_for_event_action
(
$event
);
$expires
=
JOB_LOCK_EXPIRY_IN_MINUTES
*
\
MINUTE_IN_SECONDS
;
if
(
isset
(
$this
->
concurrent_action_whitelist
[
$event
->
action
]
)
)
{
return
Lock
::
free_lock
(
$lock_key
,
$expires
);
}
else
{
return
Lock
::
reset_lock
(
$lock_key
,
$expires
);
}
}
/**
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment