2020
2121namespace Wikimedia \UUID ;
2222
23- use BagOStuff ;
24- use EmptyBagOStuff ;
2523use InvalidArgumentException ;
2624use RuntimeException ;
2725use Wikimedia \Assert \Assert ;
3432 * @since 1.35
3533 */
3634class GlobalIdGenerator {
37- /** @var BagOStuff Server-local persistent cache instance */
38- protected $ srvCache ;
3935 /** @var callable Callback for running shell commands */
4036 protected $ shellCallback ;
4137
@@ -60,7 +56,8 @@ class GlobalIdGenerator {
6056 /** @var array Cached file handles */
6157 protected $ fileHandles = []; // cached file handles
6258
63- public const QUICK_VOLATILE = 1 ; // use an APC like in-memory counter if available
59+ /** @var int B/C constant (deprecated since 1.36) */
60+ public const QUICK_VOLATILE = 1 ;
6461
6562 /**
6663 * Avoid using __CLASS__ so namespace separators aren't interpreted
@@ -81,10 +78,16 @@ class GlobalIdGenerator {
8178
8279 /**
8380 * @param string $tempDirectory A writable temporary directory
84- * @param BagOStuff $srvCache A server-local APC-like cache instance
8581 * @param callback $shellCallback A callback that takes a shell command and returns the output
8682 */
87- public function __construct ( $ tempDirectory , BagOStuff $ srvCache , callable $ shellCallback ) {
83+ public function __construct ( $ tempDirectory , $ shellCallback ) {
84+ if ( func_num_args () >= 3 && !is_callable ( $ shellCallback ) ) {
85+ trigger_error (
86+ __CLASS__ . ' with a BagOStuff instance was deprecated in MediaWiki 1.37. ' ,
87+ E_USER_DEPRECATED
88+ );
89+ $ shellCallback = func_get_arg ( 2 );
90+ }
8891 if ( !strlen ( $ tempDirectory ) ) {
8992 throw new InvalidArgumentException ( "No temp directory provided " );
9093 }
@@ -96,7 +99,6 @@ public function __construct( $tempDirectory, BagOStuff $srvCache, callable $shel
9699 $ this ->lockFile128 = $ tempDirectory . '/ ' . self ::FILE_PREFIX . '-UID-128 ' ;
97100 $ this ->lockFileUUID = $ tempDirectory . '/ ' . self ::FILE_PREFIX . '-UUID-128 ' ;
98101
99- $ this ->srvCache = $ srvCache ;
100102 $ this ->shellCallback = $ shellCallback ;
101103 }
102104
@@ -373,55 +375,39 @@ protected function getSequentialPerNodeIDs( $bucket, $bits, $count, $flags ) {
373375 throw new RuntimeException ( "Requested bit size ( $ bits) is out of range. " );
374376 }
375377
376- $ counter = null ; // post-increment persistent counter value
377-
378- // Use APC/etc if requested, available, and not in CLI mode;
379- // Counter values would not survive across script instances in CLI mode.
380- if (
381- ( $ flags & self ::QUICK_VOLATILE ) &&
382- !( $ this ->srvCache instanceof EmptyBagOStuff )
383- ) {
384- $ cache = $ this ->srvCache ;
385- $ counter = $ cache ->incrWithInit ( $ bucket , $ cache ::TTL_INDEFINITE , $ count , $ count );
386- if ( $ counter === false ) {
387- throw new RuntimeException ( 'Unable to set value to ' . get_class ( $ cache ) );
388- }
378+ $ path = $ this ->tmpDir . '/ ' . self ::FILE_PREFIX . '- ' . rawurlencode ( $ bucket ) . '-48 ' ;
379+ // Get the UID lock file handle
380+ if ( isset ( $ this ->fileHandles [$ path ] ) ) {
381+ $ handle = $ this ->fileHandles [$ path ];
382+ } else {
383+ $ handle = fopen ( $ path , 'cb+ ' );
384+ $ this ->fileHandles [$ path ] = $ handle ?: null ; // cache
389385 }
390-
391- // Note: use of fmod() avoids "division by zero" on 32 bit machines
392- if ( $ counter === null ) {
393- $ path = $ this ->tmpDir . '/ ' . self ::FILE_PREFIX . '- ' . rawurlencode ( $ bucket ) . '-48 ' ;
394- // Get the UID lock file handle
395- if ( isset ( $ this ->fileHandles [$ path ] ) ) {
396- $ handle = $ this ->fileHandles [$ path ];
397- } else {
398- $ handle = fopen ( $ path , 'cb+ ' );
399- $ this ->fileHandles [$ path ] = $ handle ?: null ; // cache
400- }
401- // Acquire the UID lock file
402- if ( $ handle === false ) {
403- throw new RuntimeException ( "Could not open ' {$ path }'. " );
404- }
405- if ( !flock ( $ handle , LOCK_EX ) ) {
406- fclose ( $ handle );
407- throw new RuntimeException ( "Could not acquire ' {$ path }'. " );
408- }
409- // Fetch the counter value and increment it...
410- rewind ( $ handle );
411- $ counter = floor ( (float )trim ( fgets ( $ handle ) ) ) + $ count ; // fetch as float
412- // Write back the new counter value
413- ftruncate ( $ handle , 0 );
414- rewind ( $ handle );
415- fwrite ( $ handle , fmod ( $ counter , 2 ** 48 ) ); // warp-around as needed
416- fflush ( $ handle );
417- // Release the UID lock file
418- flock ( $ handle , LOCK_UN );
386+ // Acquire the UID lock file
387+ if ( $ handle === false ) {
388+ throw new RuntimeException ( "Could not open ' {$ path }'. " );
419389 }
390+ if ( !flock ( $ handle , LOCK_EX ) ) {
391+ fclose ( $ handle );
392+ throw new RuntimeException ( "Could not acquire ' {$ path }'. " );
393+ }
394+ // Fetch the counter value and increment it...
395+ rewind ( $ handle );
396+ $ counter = floor ( (float )trim ( fgets ( $ handle ) ) ) + $ count ; // fetch as float
397+ // Write back the new counter value
398+ ftruncate ( $ handle , 0 );
399+ rewind ( $ handle );
400+ // Use fmod() to avoid "division by zero" on 32 bit machines
401+ fwrite ( $ handle , fmod ( $ counter , 2 ** 48 ) ); // warp-around as needed
402+ fflush ( $ handle );
403+ // Release the UID lock file
404+ flock ( $ handle , LOCK_UN );
420405
421406 $ ids = [];
422407 $ divisor = 2 ** $ bits ;
423408 $ currentId = floor ( $ counter - $ count ); // pre-increment counter value
424409 for ( $ i = 0 ; $ i < $ count ; ++$ i ) {
410+ // Use fmod() to avoid "division by zero" on 32 bit machines
425411 $ ids [] = fmod ( ++$ currentId , $ divisor );
426412 }
427413
0 commit comments