class-background-process-manager.php
3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
namespace Smush\Core\Modules\Bulk;
use Smush\Core\Modules\Background\Mutex;
class Background_Process_Manager {
const ACTIVE_PROCESSES_EXPIRATION = DAY_IN_SECONDS;
const ACTIVE_PROCESSES_KEY = 'wp_smush_bulk_smush_active_processes';
const MAX_TASKS_PER_REQUEST = 8;
private $is_multisite;
private $current_site_id;
public function __construct( $is_multisite, $current_site_id ) {
$this->is_multisite = $is_multisite;
$this->current_site_id = $current_site_id;
}
public function create_process() {
$identifier = $this->make_process_identifier();
$background_process = new Bulk_Smush_Background_Process( $identifier );
$tasks_per_request = $this->calculate_tasks_per_request();
if ( $tasks_per_request ) {
$background_process->set_tasks_per_request( $tasks_per_request );
}
$this->register( $identifier );
return $background_process;
}
public function register( $identifier ) {
$register = function ( $identifier ) {
$this->register_active_process( $identifier );
};
$unregister = function ( $identifier ) {
$this->unregister_process( $identifier );
};
add_action( "{$identifier}_started", $register );
add_action( "{$identifier}_completed", $unregister );
add_action( "{$identifier}_cancelled", $unregister );
}
private function make_process_identifier() {
$identifier = 'wp_smush_bulk_smush_background_process';
if ( $this->is_multisite ) {
$post_fix = "_" . $this->current_site_id;
$identifier .= $post_fix;
}
return $identifier;
}
private function get_active_processes() {
$active_processes = get_site_transient( self::ACTIVE_PROCESSES_KEY );
return empty( $active_processes ) || ! is_array( $active_processes )
? array()
: $active_processes;
}
private function mutex( $operation ) {
$mutex = new Mutex( self::ACTIVE_PROCESSES_KEY );
$mutex->execute( $operation );
}
private function register_active_process( $identifier ) {
$this->mutex( function () use ( $identifier ) {
$active_processes = $this->get_active_processes();
$active_processes[ $identifier ] = $identifier;
$this->set_active_processes( $active_processes );
} );
}
private function unregister_process( $identifier ) {
$this->mutex( function () use ( $identifier ) {
$active_processes = $this->get_active_processes();
unset( $active_processes[ $identifier ] );
$this->set_active_processes( $active_processes );
} );
}
private function set_active_processes( $active_processes ) {
set_site_transient(
self::ACTIVE_PROCESSES_KEY,
array_unique( $active_processes ),
self::ACTIVE_PROCESSES_EXPIRATION
);
}
private function calculate_tasks_per_request() {
$active_processes_count = count( $this->get_active_processes() );
$should_limit = $this->is_multisite && $active_processes_count > 1;
if ( ! $should_limit ) {
return false;
}
// Divide the available slots between the active processes
$tasks_per_request = intval( floor( self::MAX_TASKS_PER_REQUEST / $active_processes_count ) );
// At least 1 task per request
return max( $tasks_per_request, 1 );
}
}