class-lock.php 2.47 KB
Newer Older
1
2
<?php

3
namespace Automattic\WP\Cron_Control;
4
5
6
7

class Lock {
	/**
	 * Set a lock and limit how many concurrent jobs are permitted
8
9
10
11
12
13
	 *
	 * @param $lock     string  Lock name
	 * @param $limit    int     Concurrency limit
	 * @param $timeout  int     Timeout in seconds
	 *
	 * @return bool
14
	 */
15
	public static function check_lock( $lock, $limit = null, $timeout = null ) {
16
		// Timeout, should a process die before its lock is freed
17
		if ( ! is_numeric( $timeout ) ) {
Erick Hitter's avatar
Erick Hitter committed
18
			$timeout = LOCK_DEFAULT_TIMEOUT_IN_MINUTES * \MINUTE_IN_SECONDS;
19
20
21
22
		}

		// Check for, and recover from, deadlock
		if ( self::get_lock_timestamp( $lock ) < time() - $timeout ) {
23
24
25
26
			self::reset_lock( $lock );
			return true;
		}

27
28
		// Default limit for concurrent events
		if ( ! is_numeric( $limit ) ) {
29
			$limit = LOCK_DEFAULT_LIMIT;
30
31
		}

32
		// Check if process can run
33
		if ( self::get_lock_value( $lock ) >= $limit ) {
34
35
36
37
38
39
40
41
42
43
			return false;
		} else {
			wp_cache_incr( self::get_key( $lock ) );
			return true;
		}
	}

	/**
	 * When event completes, allow another
	 */
44
	public static function free_lock( $lock, $expires = 0 ) {
45
46
47
		if ( self::get_lock_value( $lock ) > 1 ) {
			wp_cache_decr( self::get_key( $lock ) );
		} else {
48
			wp_cache_set( self::get_key( $lock ), 0, null, $expires );
49
50
		}

51
		wp_cache_set( self::get_key( $lock, 'timestamp' ), time(), null, $expires );
52
53
54
55
56
57
58
59
60
61

		return true;
	}

	/**
	 * Build cache key
	 */
	private static function get_key( $lock, $type = 'lock' ) {
		switch ( $type ) {
			case 'lock' :
62
				return "a8ccc_lock_{$lock}";
63
64
65
				break;

			case 'timestamp' :
66
				return "a8ccc_lock_ts_{$lock}";
67
68
69
70
71
72
73
74
75
				break;
		}

		return false;
	}

	/**
	 * Ensure lock entries are initially set
	 */
76
77
78
	public static function prime_lock( $lock, $expires = 0 ) {
		wp_cache_add( self::get_key( $lock ), 0, null, $expires );
		wp_cache_add( self::get_key( $lock, 'timestamp' ), time(), null, $expires );
79
80
81
82
83
84
85

		return null;
	}

	/**
	 * Retrieve a lock from cache
	 */
86
	public static function get_lock_value( $lock ) {
87
88
89
90
91
92
		return (int) wp_cache_get( self::get_key( $lock ), null, true );
	}

	/**
	 * Retrieve a lock's timestamp
	 */
93
	public static function get_lock_timestamp( $lock ) {
94
95
96
97
98
99
		return (int) wp_cache_get( self::get_key( $lock, 'timestamp' ), null, true );
	}

	/**
	 * Clear a lock's current values, in order to free it
	 */
100
101
102
	public static function reset_lock( $lock, $expires = 0 ) {
		wp_cache_set( self::get_key( $lock ), 0, null, $expires );
		wp_cache_set( self::get_key( $lock, 'timestamp' ), time(), null, $expires );
103
104
105
106

		return true;
	}
}