Last active
September 13, 2019 23:39
-
-
Save crstauf/67de8505ae628d9589c14e62e6ef69eb to your computer and use it in GitHub Desktop.
WordPress drop-in (mu-plugin or include) to help manage features in certain server load conditions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin name: Server Load | |
* Plugin URI: https://gist.github.com/crstauf/67de8505ae628d9589c14e62e6ef69eb | |
* Author: Caleb Stauffer | |
* Author URI: https://develop.calebstauffer.com | |
* Version: 1.0 | |
*/ | |
class ServerLoad { | |
/** | |
* @var string Version number. | |
*/ | |
const VERSION = '1.0'; | |
/** | |
* @var string $load | |
*/ | |
protected $load = 'normal'; | |
/** | |
* @var string[] $loads | |
*/ | |
protected $loads = array( | |
'normal', | |
'high', | |
'extreme', | |
); | |
/** | |
* @var array $constants | |
*/ | |
protected $constants = array( | |
'EXTREME_SERVER_LOAD' => 'extreme', | |
'HIGH_SERVER_LOAD' => 'high', | |
); | |
/** | |
* Get instance. | |
* | |
* @return self | |
*/ | |
static function instance() { | |
static $_instance = null; | |
if ( is_null( $_instance ) ) | |
$_instance = new self; | |
return $_instance; | |
} | |
/** | |
* Construct. | |
* | |
* @uses $this::check_constants() | |
*/ | |
protected function __construct() { | |
$this->check_constants(); | |
add_action( 'plugins_loaded', array( $this, 'action__plugins_loaded' ) ); | |
} | |
/** | |
* Getter. | |
* | |
* @param string $key | |
*/ | |
function __get( $key ) { | |
if ( 'load' !== $key ) | |
return null; | |
return $this->load; | |
} | |
/** | |
* Setter. | |
* | |
* @param string $key | |
* @param mixed $value | |
* @uses $this::set() | |
*/ | |
function __set( $key, $value ) { | |
if ( 'load' !== $key ) | |
return null; | |
$this->set( $value ); | |
} | |
static function load() { | |
return static::instance()->load; | |
} | |
/** | |
* Check constants. | |
*/ | |
protected function check_constants() { | |
foreach ( $this->constants as $constant => $load ) { | |
# If constant not defined, define false. | |
if ( !defined( $constant ) ) | |
define( $constant, false ); | |
# If constant is defined, set load. | |
else if ( constant( $constant ) ) | |
$this->load = $load; | |
} | |
} | |
/** | |
* Set load. | |
* | |
* @param string $load | |
* @uses $this::is_valid_load() | |
*/ | |
protected function set( string $load ) { | |
if ( !$this->is_valid_load( $load ) ) { | |
trigger_error( sprintf( '<code>%s</code> is not a valid load level.', $load ) ); | |
return; | |
} | |
$this->load = $load; | |
} | |
/** | |
* Check if load is valid. | |
* | |
* @param string $load | |
* @return bool | |
*/ | |
protected function is_valid_load( string $load ) { | |
return in_array( $load, $this->loads ); | |
} | |
/** | |
* Check if is specified load. | |
* | |
* @param string|array $loads | |
* @return bool | |
*/ | |
static function is( $loads ) { | |
$loads = ( array ) $loads; | |
if ( in_array( 'high', $loads ) ) | |
$loads[] = 'extreme'; | |
return in_array( static::instance()->load, $loads ); | |
} | |
/** | |
* Action: plugins_loaded | |
* | |
* - add warning to Query Monitor if server load isn't normal | |
*/ | |
function action__plugins_loaded() { | |
if ( static::is( 'normal' ) ) | |
return; | |
do_action( 'qm/warning', sprintf( 'Server load: %s', $this->load ) ); | |
} | |
} | |
if ( !function_exists( 'add_action_if_load' ) ) { | |
/** | |
* Add action if specified load. | |
* | |
* @see add_action() | |
* @param string|array $loads | |
* @uses ServerLoad::is() | |
* @uses add_action() | |
*/ | |
function add_action_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) { | |
if ( !ServerLoad::is( $loads ) ) | |
return; | |
add_action( $hook, $callback, $priority, $accepted_args ); | |
} | |
} | |
if ( !function_exists( 'add_filter_if_load' ) ) { | |
/** | |
* Add filter if specified load. | |
* | |
* @see add_filter() | |
* @param string|array $loads | |
* @uses ServerLoad::is() | |
* @uses add_filter() | |
*/ | |
function add_filter_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) { | |
if ( !ServerLoad::is( $loads ) ) | |
return; | |
add_filter( $hook, $callback, $priority, $accepted_args ); | |
} | |
} | |
if ( !function_exists( 'remove_action_if_load' ) ) { | |
/** | |
* Remove action if specified load. | |
* | |
* @see add_action() | |
* @param string|array $loads | |
* @uses ServerLoad::is() | |
* @uses remove_action() | |
*/ | |
function remove_action_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) { | |
if ( !ServerLoad::is( $loads ) ) | |
return; | |
if ( class_exists( 'QM_Util' ) ) | |
do_action( 'qm/info', sprintf( '<code>%s</code> on <code>%s</code> action prevented due to %s server load.', QM_Util::populate_callback( array( 'function' => $callback ) )['function'], $hook, ServerLoad::load() ) ); | |
remove_action( $hook, $callback, $priority, $accepted_args ); | |
} | |
} | |
if ( !function_exists( 'remove_filter_if_load' ) ) { | |
/** | |
* Remove filter if specified load. | |
* | |
* @see add_filter() | |
* @param string|array $loads | |
* @uses ServerLoad::is() | |
* @uses add_filter() | |
*/ | |
function remove_filter_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) { | |
if ( !ServerLoad::is( $loads ) ) | |
return; | |
if ( class_exists( 'QM_Util' ) ) | |
do_action( 'qm/info', sprintf( '<code>%s</code> on <code>%s</code> filter prevented due to %s server load.', QM_Util::populate_callback( array( 'function' => $callback ) )['function'], $hook, ServerLoad::load() ) ); | |
remove_filter( $hook, $callback, $priority, $accepted_args ); | |
} | |
} | |
ServerLoad::instance(); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment