MediaWiki  1.28.3
LBFactory.php
Go to the documentation of this file.
1 <?php
26 
31 abstract class LBFactory implements ILBFactory {
33  protected $chronProt;
35  protected $profiler;
37  protected $trxProfiler;
39  protected $replLogger;
41  protected $connLogger;
43  protected $queryLogger;
45  protected $perfLogger;
47  protected $errorLogger;
49  protected $srvCache;
51  protected $memCache;
53  protected $wanCache;
54 
56  protected $localDomain;
58  protected $hostname;
60  protected $requestInfo;
61 
63  protected $ticket;
65  protected $trxRoundId = false;
67  protected $readOnlyReason = false;
69  protected $replicationWaitCallbacks = [];
70 
72  protected $cliMode;
74  protected $agent;
75 
76  private static $loggerFields =
77  [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ];
78 
79  public function __construct( array $conf ) {
80  $this->localDomain = isset( $conf['localDomain'] )
81  ? DatabaseDomain::newFromId( $conf['localDomain'] )
83 
84  if ( isset( $conf['readOnlyReason'] ) && is_string( $conf['readOnlyReason'] ) ) {
85  $this->readOnlyReason = $conf['readOnlyReason'];
86  }
87 
88  $this->srvCache = isset( $conf['srvCache'] ) ? $conf['srvCache'] : new EmptyBagOStuff();
89  $this->memCache = isset( $conf['memCache'] ) ? $conf['memCache'] : new EmptyBagOStuff();
90  $this->wanCache = isset( $conf['wanCache'] )
91  ? $conf['wanCache']
93 
94  foreach ( self::$loggerFields as $key ) {
95  $this->$key = isset( $conf[$key] ) ? $conf[$key] : new \Psr\Log\NullLogger();
96  }
97  $this->errorLogger = isset( $conf['errorLogger'] )
98  ? $conf['errorLogger']
99  : function ( Exception $e ) {
100  trigger_error( E_USER_WARNING, get_class( $e ) . ': ' . $e->getMessage() );
101  };
102 
103  $this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
104  $this->trxProfiler = isset( $conf['trxProfiler'] )
105  ? $conf['trxProfiler']
106  : new TransactionProfiler();
107 
108  $this->requestInfo = [
109  'IPAddress' => isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '',
110  'UserAgent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
111  'ChronologyProtection' => 'true'
112  ];
113 
114  $this->cliMode = isset( $params['cliMode'] ) ? $params['cliMode'] : PHP_SAPI === 'cli';
115  $this->hostname = isset( $conf['hostname'] ) ? $conf['hostname'] : gethostname();
116  $this->agent = isset( $params['agent'] ) ? $params['agent'] : '';
117 
118  $this->ticket = mt_rand();
119  }
120 
121  public function destroy() {
122  $this->shutdown( self::SHUTDOWN_NO_CHRONPROT );
123  $this->forEachLBCallMethod( 'disable' );
124  }
125 
126  public function shutdown(
127  $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null
128  ) {
130  if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
131  $this->shutdownChronologyProtector( $chronProt, $workCallback, 'sync' );
132  } elseif ( $mode === self::SHUTDOWN_CHRONPROT_ASYNC ) {
133  $this->shutdownChronologyProtector( $chronProt, null, 'async' );
134  }
135 
136  $this->commitMasterChanges( __METHOD__ ); // sanity
137  }
138 
144  abstract public function newMainLB( $domain = false );
145 
151  abstract public function getMainLB( $domain = false );
152 
158  abstract public function newExternalLB( $cluster );
159 
165  abstract public function getExternalLB( $cluster );
166 
173  protected function forEachLBCallMethod( $methodName, array $args = [] ) {
174  $this->forEachLB(
175  function ( ILoadBalancer $loadBalancer, $methodName, array $args ) {
176  call_user_func_array( [ $loadBalancer, $methodName ], $args );
177  },
178  [ $methodName, $args ]
179  );
180  }
181 
182  public function flushReplicaSnapshots( $fname = __METHOD__ ) {
183  $this->forEachLBCallMethod( 'flushReplicaSnapshots', [ $fname ] );
184  }
185 
186  public function commitAll( $fname = __METHOD__, array $options = [] ) {
188  $this->forEachLBCallMethod( 'commitAll', [ $fname ] );
189  }
190 
191  public function beginMasterChanges( $fname = __METHOD__ ) {
192  if ( $this->trxRoundId !== false ) {
193  throw new DBTransactionError(
194  null,
195  "$fname: transaction round '{$this->trxRoundId}' already started."
196  );
197  }
198  $this->trxRoundId = $fname;
199  // Set DBO_TRX flags on all appropriate DBs
200  $this->forEachLBCallMethod( 'beginMasterChanges', [ $fname ] );
201  }
202 
203  public function commitMasterChanges( $fname = __METHOD__, array $options = [] ) {
204  if ( $this->trxRoundId !== false && $this->trxRoundId !== $fname ) {
205  throw new DBTransactionError(
206  null,
207  "$fname: transaction round '{$this->trxRoundId}' still running."
208  );
209  }
211  $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
212  // Run pre-commit callbacks and suppress post-commit callbacks, aborting on failure
213  $this->forEachLBCallMethod( 'finalizeMasterChanges' );
214  $this->trxRoundId = false;
215  // Perform pre-commit checks, aborting on failure
216  $this->forEachLBCallMethod( 'approveMasterChanges', [ $options ] );
217  // Log the DBs and methods involved in multi-DB transactions
218  $this->logIfMultiDbTransaction();
219  // Actually perform the commit on all master DB connections and revert DBO_TRX
220  $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
221  // Run all post-commit callbacks
223  $e = null; // first callback exception
224  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$e ) {
225  $ex = $lb->runMasterPostTrxCallbacks( IDatabase::TRIGGER_COMMIT );
226  $e = $e ?: $ex;
227  } );
228  // Commit any dangling DBO_TRX transactions from callbacks on one DB to another DB
229  $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
230  // Throw any last post-commit callback error
231  if ( $e instanceof Exception ) {
232  throw $e;
233  }
234  }
235 
236  public function rollbackMasterChanges( $fname = __METHOD__ ) {
237  $this->trxRoundId = false;
238  $this->forEachLBCallMethod( 'suppressTransactionEndCallbacks' );
239  $this->forEachLBCallMethod( 'rollbackMasterChanges', [ $fname ] );
240  // Run all post-rollback callbacks
241  $this->forEachLB( function ( ILoadBalancer $lb ) {
242  $lb->runMasterPostTrxCallbacks( IDatabase::TRIGGER_ROLLBACK );
243  } );
244  }
245 
246  public function hasTransactionRound() {
247  return ( $this->trxRoundId !== false );
248  }
249 
253  private function logIfMultiDbTransaction() {
254  $callersByDB = [];
255  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$callersByDB ) {
256  $masterName = $lb->getServerName( $lb->getWriterIndex() );
257  $callers = $lb->pendingMasterChangeCallers();
258  if ( $callers ) {
259  $callersByDB[$masterName] = $callers;
260  }
261  } );
262 
263  if ( count( $callersByDB ) >= 2 ) {
264  $dbs = implode( ', ', array_keys( $callersByDB ) );
265  $msg = "Multi-DB transaction [{$dbs}]:\n";
266  foreach ( $callersByDB as $db => $callers ) {
267  $msg .= "$db: " . implode( '; ', $callers ) . "\n";
268  }
269  $this->queryLogger->info( $msg );
270  }
271  }
272 
273  public function hasMasterChanges() {
274  $ret = false;
275  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$ret ) {
276  $ret = $ret || $lb->hasMasterChanges();
277  } );
278 
279  return $ret;
280  }
281 
282  public function laggedReplicaUsed() {
283  $ret = false;
284  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$ret ) {
285  $ret = $ret || $lb->laggedReplicaUsed();
286  } );
287 
288  return $ret;
289  }
290 
291  public function hasOrMadeRecentMasterChanges( $age = null ) {
292  $ret = false;
293  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $age, &$ret ) {
294  $ret = $ret || $lb->hasOrMadeRecentMasterChanges( $age );
295  } );
296  return $ret;
297  }
298 
299  public function waitForReplication( array $opts = [] ) {
300  $opts += [
301  'domain' => false,
302  'cluster' => false,
303  'timeout' => 60,
304  'ifWritesSince' => null
305  ];
306 
307  if ( $opts['domain'] === false && isset( $opts['wiki'] ) ) {
308  $opts['domain'] = $opts['wiki']; // b/c
309  }
310 
311  // Figure out which clusters need to be checked
313  $lbs = [];
314  if ( $opts['cluster'] !== false ) {
315  $lbs[] = $this->getExternalLB( $opts['cluster'] );
316  } elseif ( $opts['domain'] !== false ) {
317  $lbs[] = $this->getMainLB( $opts['domain'] );
318  } else {
319  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$lbs ) {
320  $lbs[] = $lb;
321  } );
322  if ( !$lbs ) {
323  return; // nothing actually used
324  }
325  }
326 
327  // Get all the master positions of applicable DBs right now.
328  // This can be faster since waiting on one cluster reduces the
329  // time needed to wait on the next clusters.
330  $masterPositions = array_fill( 0, count( $lbs ), false );
331  foreach ( $lbs as $i => $lb ) {
332  if ( $lb->getServerCount() <= 1 ) {
333  // Bug 27975 - Don't try to wait for replica DBs if there are none
334  // Prevents permission error when getting master position
335  continue;
336  } elseif ( $opts['ifWritesSince']
337  && $lb->lastMasterChangeTimestamp() < $opts['ifWritesSince']
338  ) {
339  continue; // no writes since the last wait
340  }
341  $masterPositions[$i] = $lb->getMasterPos();
342  }
343 
344  // Run any listener callbacks *after* getting the DB positions. The more
345  // time spent in the callbacks, the less time is spent in waitForAll().
346  foreach ( $this->replicationWaitCallbacks as $callback ) {
347  $callback();
348  }
349 
350  $failed = [];
351  foreach ( $lbs as $i => $lb ) {
352  if ( $masterPositions[$i] ) {
353  // The DBMS may not support getMasterPos()
354  if ( !$lb->waitForAll( $masterPositions[$i], $opts['timeout'] ) ) {
355  $failed[] = $lb->getServerName( $lb->getWriterIndex() );
356  }
357  }
358  }
359 
360  if ( $failed ) {
361  throw new DBReplicationWaitError(
362  "Could not wait for replica DBs to catch up to " .
363  implode( ', ', $failed )
364  );
365  }
366  }
367 
368  public function setWaitForReplicationListener( $name, callable $callback = null ) {
369  if ( $callback ) {
370  $this->replicationWaitCallbacks[$name] = $callback;
371  } else {
372  unset( $this->replicationWaitCallbacks[$name] );
373  }
374  }
375 
376  public function getEmptyTransactionTicket( $fname ) {
377  if ( $this->hasMasterChanges() ) {
378  $this->queryLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
379  ( new RuntimeException() )->getTraceAsString() );
380 
381  return null;
382  }
383 
384  return $this->ticket;
385  }
386 
387  public function commitAndWaitForReplication( $fname, $ticket, array $opts = [] ) {
388  if ( $ticket !== $this->ticket ) {
389  $this->perfLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
390  ( new RuntimeException() )->getTraceAsString() );
391 
392  return;
393  }
394 
395  // The transaction owner and any caller with the empty transaction ticket can commit
396  // so that getEmptyTransactionTicket() callers don't risk seeing DBTransactionError.
397  if ( $this->trxRoundId !== false && $fname !== $this->trxRoundId ) {
398  $this->queryLogger->info( "$fname: committing on behalf of {$this->trxRoundId}." );
399  $fnameEffective = $this->trxRoundId;
400  } else {
401  $fnameEffective = $fname;
402  }
403 
404  $this->commitMasterChanges( $fnameEffective );
405  $this->waitForReplication( $opts );
406  // If a nested caller committed on behalf of $fname, start another empty $fname
407  // transaction, leaving the caller with the same empty transaction state as before.
408  if ( $fnameEffective !== $fname ) {
409  $this->beginMasterChanges( $fnameEffective );
410  }
411  }
412 
413  public function getChronologyProtectorTouched( $dbName ) {
414  return $this->getChronologyProtector()->getTouched( $dbName );
415  }
416 
417  public function disableChronologyProtection() {
418  $this->getChronologyProtector()->setEnabled( false );
419  }
420 
424  protected function getChronologyProtector() {
425  if ( $this->chronProt ) {
426  return $this->chronProt;
427  }
428 
429  $this->chronProt = new ChronologyProtector(
430  $this->memCache,
431  [
432  'ip' => $this->requestInfo['IPAddress'],
433  'agent' => $this->requestInfo['UserAgent'],
434  ],
435  isset( $_GET['cpPosTime'] ) ? $_GET['cpPosTime'] : null
436  );
437  $this->chronProt->setLogger( $this->replLogger );
438 
439  if ( $this->cliMode ) {
440  $this->chronProt->setEnabled( false );
441  } elseif ( $this->requestInfo['ChronologyProtection'] === 'false' ) {
442  // Request opted out of using position wait logic. This is useful for requests
443  // done by the job queue or background ETL that do not have a meaningful session.
444  $this->chronProt->setWaitEnabled( false );
445  }
446 
447  $this->replLogger->debug( __METHOD__ . ': using request info ' .
448  json_encode( $this->requestInfo, JSON_PRETTY_PRINT ) );
449 
450  return $this->chronProt;
451  }
452 
460  protected function shutdownChronologyProtector(
461  ChronologyProtector $cp, $workCallback, $mode
462  ) {
463  // Record all the master positions needed
464  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $cp ) {
465  $cp->shutdownLB( $lb );
466  } );
467  // Write them to the persistent stash. Try to do something useful by running $work
468  // while ChronologyProtector waits for the stash write to replicate to all DCs.
469  $unsavedPositions = $cp->shutdown( $workCallback, $mode );
470  if ( $unsavedPositions && $workCallback ) {
471  // Invoke callback in case it did not cache the result yet
472  $workCallback(); // work now to block for less time in waitForAll()
473  }
474  // If the positions failed to write to the stash, at least wait on local datacenter
475  // replica DBs to catch up before responding. Even if there are several DCs, this increases
476  // the chance that the user will see their own changes immediately afterwards. As long
477  // as the sticky DC cookie applies (same domain), this is not even an issue.
478  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $unsavedPositions ) {
479  $masterName = $lb->getServerName( $lb->getWriterIndex() );
480  if ( isset( $unsavedPositions[$masterName] ) ) {
481  $lb->waitForAll( $unsavedPositions[$masterName] );
482  }
483  } );
484  }
485 
490  final protected function baseLoadBalancerParams() {
491  return [
492  'localDomain' => $this->localDomain,
493  'readOnlyReason' => $this->readOnlyReason,
494  'srvCache' => $this->srvCache,
495  'wanCache' => $this->wanCache,
496  'profiler' => $this->profiler,
497  'trxProfiler' => $this->trxProfiler,
498  'queryLogger' => $this->queryLogger,
499  'connLogger' => $this->connLogger,
500  'replLogger' => $this->replLogger,
501  'errorLogger' => $this->errorLogger,
502  'hostname' => $this->hostname,
503  'cliMode' => $this->cliMode,
504  'agent' => $this->agent
505  ];
506  }
507 
511  protected function initLoadBalancer( ILoadBalancer $lb ) {
512  if ( $this->trxRoundId !== false ) {
513  $lb->beginMasterChanges( $this->trxRoundId ); // set DBO_TRX
514  }
515  }
516 
517  public function setDomainPrefix( $prefix ) {
518  $this->localDomain = new DatabaseDomain(
519  $this->localDomain->getDatabase(),
520  null,
521  $prefix
522  );
523 
524  $this->forEachLB( function( ILoadBalancer $lb ) use ( $prefix ) {
525  $lb->setDomainPrefix( $prefix );
526  } );
527  }
528 
529  public function closeAll() {
530  $this->forEachLBCallMethod( 'closeAll', [] );
531  }
532 
533  public function setAgentName( $agent ) {
534  $this->agent = $agent;
535  }
536 
537  public function appendPreShutdownTimeAsQuery( $url, $time ) {
538  $usedCluster = 0;
539  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$usedCluster ) {
540  $usedCluster |= ( $lb->getServerCount() > 1 );
541  } );
542 
543  if ( !$usedCluster ) {
544  return $url; // no master/replica clusters touched
545  }
546 
547  return strpos( $url, '?' ) === false ? "$url?cpPosTime=$time" : "$url&cpPosTime=$time";
548  }
549 
550  public function setRequestInfo( array $info ) {
551  $this->requestInfo = $info + $this->requestInfo;
552  }
553 
560  final protected function getScopedPHPBehaviorForCommit() {
561  if ( PHP_SAPI != 'cli' ) { // http://bugs.php.net/bug.php?id=47540
562  $old = ignore_user_abort( true ); // avoid half-finished operations
563  return new ScopedCallback( function () use ( $old ) {
564  ignore_user_abort( $old );
565  } );
566  }
567 
568  return null;
569  }
570 
571  function __destruct() {
572  $this->destroy();
573  }
574 }
beginMasterChanges($fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
Definition: LBFactory.php:191
runMasterPostTrxCallbacks($type)
Issue all pending post-COMMIT/ROLLBACK callbacks.
mixed $ticket
Definition: LBFactory.php:63
the array() calling protocol came about after MediaWiki 1.4rc1.
static newUnspecified()
LoggerInterface $perfLogger
Definition: LBFactory.php:45
LoggerInterface $queryLogger
Definition: LBFactory.php:43
baseLoadBalancerParams()
Base parameters to LoadBalancer::__construct()
Definition: LBFactory.php:490
beginMasterChanges($fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
bool $cliMode
Whether this PHP instance is for a CLI script.
Definition: LBFactory.php:72
setAgentName($agent)
Definition: LBFactory.php:533
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
Definition: hooks.txt:1940
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
newMainLB($domain=false)
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
Definition: hooks.txt:2106
__construct(array $conf)
Construct a manager of ILoadBalancer objects.
Definition: LBFactory.php:79
An interface for generating database load balancers.
Definition: ILBFactory.php:29
callable[] $replicationWaitCallbacks
Definition: LBFactory.php:69
commitAll($fname=__METHOD__, array $options=[])
Commit open transactions on all connections.
Definition: LBFactory.php:186
BagOStuff $srvCache
Definition: LBFactory.php:49
shutdownLB(ILoadBalancer $lb)
Notify the ChronologyProtector that the ILoadBalancer is about to shut down.
forEachLB($callback, array $params=[])
Execute a function for each tracked load balancer The callback is called with the load balancer as th...
getChronologyProtectorTouched($dbName)
Definition: LBFactory.php:413
getMainLB($domain=false)
object string $profiler
Class name or object With profileIn/profileOut methods.
Definition: LBFactory.php:35
laggedReplicaUsed()
Detemine if any lagged replica DB connection was used.
Definition: LBFactory.php:282
shutdownChronologyProtector(ChronologyProtector $cp, $workCallback, $mode)
Get and record all of the staged DB positions into persistent memory storage.
Definition: LBFactory.php:460
commitMasterChanges($fname=__METHOD__, array $options=[])
Commit changes on all master connections.
Definition: LBFactory.php:203
if($line===false) $args
Definition: cdb.php:64
Class to handle database/prefix specification for IDatabase domains.
shutdown(callable $workCallback=null, $mode= 'sync')
Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now...
getExternalLB($cluster)
shutdown($mode=self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback=null)
Prepare all tracked load balancers for shutdown.
Definition: LBFactory.php:126
static newEmpty()
Get an instance that wraps EmptyBagOStuff.
initLoadBalancer(ILoadBalancer $lb)
Definition: LBFactory.php:511
array $requestInfo
Web request information about the client.
Definition: LBFactory.php:60
waitForAll($pos, $timeout=null)
Set the master wait position and wait for ALL replica DBs to catch up to it.
rollbackMasterChanges($fname=__METHOD__)
Rollback changes on all master connections.
Definition: LBFactory.php:236
DatabaseDomain $localDomain
Local domain.
Definition: LBFactory.php:56
newExternalLB($cluster)
Exception class for replica DB wait timeouts.
callable $errorLogger
Error logger.
Definition: LBFactory.php:47
hasMasterChanges()
Determine if there are pending changes in a transaction by this thread.
appendPreShutdownTimeAsQuery($url, $time)
Append ?cpPosTime parameter to a URL for ChronologyProtector purposes if needed.
Definition: LBFactory.php:537
waitForReplication(array $opts=[])
Waits for the replica DBs to catch up to the current master position.
Definition: LBFactory.php:299
string $agent
Agent name for query profiling.
Definition: LBFactory.php:74
Database cluster connection, tracking, load balancing, and transaction manager interface.
Helper class that detects high-contention DB queries via profiling calls.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
Definition: hooks.txt:1050
hasMasterChanges()
Determine if any master connection has pending changes.
Definition: LBFactory.php:273
string bool $trxRoundId
String if a requested DBO_TRX transaction round is active.
Definition: LBFactory.php:65
hasTransactionRound()
Check if a transaction round is active.
Definition: LBFactory.php:246
$params
string bool $readOnlyReason
Reason all LBs are read-only or false if not.
Definition: LBFactory.php:67
pendingMasterChangeCallers()
Get the list of callers that have pending master changes.
closeAll()
Close all open database connections on all open load balancers.
Definition: LBFactory.php:529
A BagOStuff object with no objects in it.
WANObjectCache $wanCache
Definition: LBFactory.php:53
BagOStuff $memCache
Definition: LBFactory.php:51
disableChronologyProtection()
Disable the ChronologyProtector for all load balancers.
Definition: LBFactory.php:417
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
setDomainPrefix($prefix)
Set a new table prefix for the existing local domain ID for testing.
Definition: LBFactory.php:517
getServerCount()
Get the number of defined servers (not the number of open connections)
LoggerInterface $replLogger
Definition: LBFactory.php:39
forEachLBCallMethod($methodName, array $args=[])
Call a method of each tracked load balancer.
Definition: LBFactory.php:173
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
commitAndWaitForReplication($fname, $ticket, array $opts=[])
Convenience method for safely running commitMasterChanges()/waitForReplication()
Definition: LBFactory.php:387
Class for ensuring a consistent ordering of events as seen by the user, despite replication.
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined...
Definition: Setup.php:36
hasOrMadeRecentMasterChanges($age=null)
Check if this load balancer object had any recent or still pending writes issued against it by this P...
hasOrMadeRecentMasterChanges($age=null)
Determine if any master connection has pending/written changes from this request. ...
Definition: LBFactory.php:291
static newFromId($domain)
setWaitForReplicationListener($name, callable $callback=null)
Add a callback to be run in every call to waitForReplication() before waiting.
Definition: LBFactory.php:368
destroy()
Disables all load balancers.
Definition: LBFactory.php:121
setDomainPrefix($prefix)
Set a new table prefix for the existing local domain ID for testing.
getScopedPHPBehaviorForCommit()
Make PHP ignore user aborts/disconnects until the returned value leaves scope.
Definition: LBFactory.php:560
string $hostname
Local hostname of the app server.
Definition: LBFactory.php:58
static $loggerFields
Definition: LBFactory.php:76
LoggerInterface $connLogger
Definition: LBFactory.php:41
TransactionProfiler $trxProfiler
Definition: LBFactory.php:37
getServerName($i)
Get the host name or IP address of the server with the specified index Prefer a readable name if avai...
getChronologyProtector()
Definition: LBFactory.php:424
setRequestInfo(array $info)
Definition: LBFactory.php:550
flushReplicaSnapshots($fname=__METHOD__)
Commit all replica DB transactions so as to flush any REPEATABLE-READ or SSI snapshot.
Definition: LBFactory.php:182
logIfMultiDbTransaction()
Log query info if multi DB transactions are going to be committed now.
Definition: LBFactory.php:253
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1753
getEmptyTransactionTicket($fname)
Get a token asserting that no transaction writes are active.
Definition: LBFactory.php:376
ChronologyProtector $chronProt
Definition: LBFactory.php:33
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304