1 | <?php |
||
28 | class ChronologyProtector { |
||
29 | /** @var BagOStuff */ |
||
30 | protected $store; |
||
31 | |||
32 | /** @var string Storage key name */ |
||
33 | protected $key; |
||
34 | /** @var string Hash of client parameters */ |
||
35 | protected $clientId; |
||
36 | /** @var float|null Minimum UNIX timestamp of 1+ expected startup positions */ |
||
37 | protected $waitForPosTime; |
||
38 | /** @var int Max seconds to wait on positions to appear */ |
||
39 | protected $waitForPosTimeout = self::POS_WAIT_TIMEOUT; |
||
40 | /** @var bool Whether to no-op all method calls */ |
||
41 | protected $enabled = true; |
||
42 | /** @var bool Whether to check and wait on positions */ |
||
43 | protected $wait = true; |
||
44 | |||
45 | /** @var bool Whether the client data was loaded */ |
||
46 | protected $initialized = false; |
||
47 | /** @var DBMasterPos[] Map of (DB master name => position) */ |
||
48 | protected $startupPositions = []; |
||
49 | /** @var DBMasterPos[] Map of (DB master name => position) */ |
||
50 | protected $shutdownPositions = []; |
||
51 | /** @var float[] Map of (DB master name => 1) */ |
||
52 | protected $shutdownTouchDBs = []; |
||
53 | |||
54 | /** @var integer Seconds to store positions */ |
||
55 | const POSITION_TTL = 60; |
||
56 | /** @var integer Max time to wait for positions to appear */ |
||
57 | const POS_WAIT_TIMEOUT = 5; |
||
58 | |||
59 | /** |
||
60 | * @param BagOStuff $store |
||
61 | * @param array $client Map of (ip: <IP>, agent: <user-agent>) |
||
62 | * @param float $posTime UNIX timestamp |
||
63 | * @since 1.27 |
||
64 | */ |
||
65 | public function __construct( BagOStuff $store, array $client, $posTime = null ) { |
||
71 | |||
72 | /** |
||
73 | * @param bool $enabled Whether to no-op all method calls |
||
74 | * @since 1.27 |
||
75 | */ |
||
76 | public function setEnabled( $enabled ) { |
||
79 | |||
80 | /** |
||
81 | * @param bool $enabled Whether to check and wait on positions |
||
82 | * @since 1.27 |
||
83 | */ |
||
84 | public function setWaitEnabled( $enabled ) { |
||
87 | |||
88 | /** |
||
89 | * Initialise a LoadBalancer to give it appropriate chronology protection. |
||
90 | * |
||
91 | * If the stash has a previous master position recorded, this will try to |
||
92 | * make sure that the next query to a replica DB of that master will see changes up |
||
93 | * to that position by delaying execution. The delay may timeout and allow stale |
||
94 | * data if no non-lagged replica DBs are available. |
||
95 | * |
||
96 | * @param LoadBalancer $lb |
||
97 | * @return void |
||
98 | */ |
||
99 | public function initLB( LoadBalancer $lb ) { |
||
113 | |||
114 | /** |
||
115 | * Notify the ChronologyProtector that the LoadBalancer is about to shut |
||
116 | * down. Saves replication positions. |
||
117 | * |
||
118 | * @param LoadBalancer $lb |
||
119 | * @return void |
||
120 | */ |
||
121 | public function shutdownLB( LoadBalancer $lb ) { |
||
139 | |||
140 | /** |
||
141 | * Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now. |
||
142 | * May commit chronology data to persistent storage. |
||
143 | * |
||
144 | * @param callable|null $workCallback Work to do instead of waiting on syncing positions |
||
145 | * @param string $mode One of (sync, async); whether to wait on remote datacenters |
||
146 | * @return DBMasterPos[] Empty on success; returns the (db name => position) map on failure |
||
147 | */ |
||
148 | public function shutdown( callable $workCallback = null, $mode = 'sync' ) { |
||
213 | |||
214 | /** |
||
215 | * @param string $dbName DB master name (e.g. "db1052") |
||
216 | * @return float|bool UNIX timestamp when client last touched the DB; false if not on record |
||
217 | * @since 1.28 |
||
218 | */ |
||
219 | public function getTouched( $dbName ) { |
||
222 | |||
223 | /** |
||
224 | * @param BagOStuff $store |
||
225 | * @param string $dbName |
||
226 | * @return string |
||
227 | */ |
||
228 | private function getTouchedKey( BagOStuff $store, $dbName ) { |
||
231 | |||
232 | /** |
||
233 | * Load in previous master positions for the client |
||
234 | */ |
||
235 | protected function initPositions() { |
||
276 | |||
277 | /** |
||
278 | * @param array|bool $data |
||
279 | * @return float|null |
||
280 | */ |
||
281 | private static function minPosTime( $data ) { |
||
294 | |||
295 | /** |
||
296 | * @param array|bool $curValue |
||
297 | * @param DBMasterPos[] $shutdownPositions |
||
298 | * @return array |
||
299 | */ |
||
300 | private static function mergePositions( $curValue, array $shutdownPositions ) { |
||
318 | } |
||
319 |