}
}
- // Ignore warnings about master connections/writes...hard to avoid here
- \Profiler::instance()->getTransactionProfiler()->resetExpectations();
-
$backoffKey = wfMemcKey( 'AuthManager', 'autocreate-failed', md5( $username ) );
if ( $cache->get( $backoffKey ) ) {
$this->logger->debug( __METHOD__ . ': {username} denied by prior creation attempt failures', [
'from' => $from,
] );
+ // Ignore warnings about master connections/writes...hard to avoid here
+ $trxProfiler = \Profiler::instance()->getTransactionProfiler();
+ $trxProfiler->setSilenced( true );
try {
$status = $user->addToDatabase();
if ( !$status->isOk() ) {
return $status;
}
} catch ( \Exception $ex ) {
+ $trxProfiler->setSilenced( false );
$this->logger->error( __METHOD__ . ': {username} failed with exception {exception}', [
'username' => $username,
'exception' => $ex,
// Update user count
\DeferredUpdates::addUpdate( new \SiteStatsUpdate( 0, 0, 0, 0, 1 ) );
-
// Watch user's userpage and talk page
- $user->addWatch( $user->getUserPage(), User::IGNORE_USER_RIGHTS );
+ \DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+ $user->addWatch( $user->getUserPage(), User::IGNORE_USER_RIGHTS );
+ } );
// Log the creation
if ( $this->config->get( 'NewUserLog' ) ) {
// the newly-created user doesn't get lost.
wfGetLBFactory()->commitMasterChanges( __METHOD__ );
+ $trxProfiler->setSilenced( false );
+
if ( $login ) {
$this->setSessionDataForUser( $user );
}
*
* This is meant for multi-wiki systems that may share files.
*
- * All lock requests for a resource, identified by a hash string, will map
- * to one bucket. Each bucket maps to one or several peer DBs, each on their
- * own server, all having the filelocks.sql tables (with row-level locking).
+ * All lock requests for a resource, identified by a hash string, will map to one bucket.
+ * Each bucket maps to one or several peer DBs, each on their own server.
* A majority of peer DBs must agree for a lock to be acquired.
*
* Caching is used to avoid hitting servers that are down.
/**
* MySQL version of DBLockManager that supports shared locks.
+ *
+ * All lock servers must have the innodb table defined in locking/filelocks.sql.
* All locks are non-blocking, which avoids deadlocks.
*
* @ingroup LockManager
/** @var bool Whether the row was upgraded on load */
private $upgraded;
+ /** @var bool Whether the row was scheduled to upgrade on load */
+ private $upgrading;
+
/** @var bool True if the image row is locked */
private $locked;
*/
function maybeUpgradeRow() {
global $wgUpdateCompatibleMetadata;
- if ( wfReadOnly() ) {
+
+ if ( wfReadOnly() || $this->upgrading ) {
return;
}
$upgrade = false;
- if ( is_null( $this->media_type ) ||
- $this->mime == 'image/svg'
- ) {
+ if ( is_null( $this->media_type ) || $this->mime == 'image/svg' ) {
$upgrade = true;
} else {
$handler = $this->getHandler();
if ( $handler ) {
$validity = $handler->isMetadataValid( $this, $this->getMetadata() );
- if ( $validity === MediaHandler::METADATA_BAD
- || ( $validity === MediaHandler::METADATA_COMPATIBLE && $wgUpdateCompatibleMetadata )
- ) {
+ if ( $validity === MediaHandler::METADATA_BAD ) {
$upgrade = true;
+ } elseif ( $validity === MediaHandler::METADATA_COMPATIBLE ) {
+ $upgrade = $wgUpdateCompatibleMetadata;
}
}
}
if ( $upgrade ) {
- try {
- $this->upgradeRow();
- } catch ( LocalFileLockError $e ) {
- // let the other process handle it (or do it next time)
- }
- $this->upgraded = true; // avoid rework/retries
+ $this->upgrading = true;
+ // Defer updates unless in auto-commit CLI mode
+ DeferredUpdates::addCallableUpdate( function() {
+ $this->upgrading = false; // avoid duplicate updates
+ try {
+ $this->upgradeRow();
+ } catch ( LocalFileLockError $e ) {
+ // let the other process handle it (or do it next time)
+ }
+ } );
}
}
+ /**
+ * @return bool Whether upgradeRow() ran for this object
+ */
function getUpgraded() {
return $this->upgraded;
}
$this->invalidateCache();
$this->unlock(); // done
-
+ $this->upgraded = true; // avoid rework/retries
}
/**
DeferredUpdates::addUpdate( new CdnCacheUpdate( $urls ), DeferredUpdates::PRESEND );
}
+ /**
+ * Prerenders a configurable set of thumbnails
+ *
+ * @since 1.28
+ */
+ public function prerenderThumbnails() {
+ global $wgUploadThumbnailRenderMap;
+
+ $jobs = [];
+
+ $sizes = $wgUploadThumbnailRenderMap;
+ rsort( $sizes );
+
+ foreach ( $sizes as $size ) {
+ if ( $this->isVectorized() || $this->getWidth() > $size ) {
+ $jobs[] = new ThumbnailRenderJob(
+ $this->getTitle(),
+ [ 'transformParams' => [ 'width' => $size ] ]
+ );
+ }
+ }
+
+ if ( $jobs ) {
+ JobQueueGroup::singleton()->lazyPush( $jobs );
+ }
+ }
+
/**
* Delete a list of thumbnails visible at urls
* @param string $dir Base dir of the files.
# Update backlink pages pointing to this title if created
LinksUpdate::queueRecursiveJobsForTable( $this->getTitle(), 'imagelinks' );
}
+
+ $this->prerenderThumbnails();
}
),
DeferredUpdates::PRESEND
* @since 1.25
*/
public function postProcessUpload() {
- global $wgUploadThumbnailRenderMap;
-
- $jobs = [];
-
- $sizes = $wgUploadThumbnailRenderMap;
- rsort( $sizes );
-
- $file = $this->getLocalFile();
-
- foreach ( $sizes as $size ) {
- if ( $file->isVectorized() || $file->getWidth() > $size ) {
- $jobs[] = new ThumbnailRenderJob(
- $file->getTitle(),
- [ 'transformParams' => [ 'width' => $size ] ]
- );
- }
- }
-
- if ( $jobs ) {
- JobQueueGroup::singleton()->push( $jobs );
- }
}
/**
}
foreach ( $res as $row ) {
+ // LocalFile will upgrade immediately here if obsolete
$file = $repo->newFileFromRow( $row );
if ( $file->getUpgraded() ) {
// File was upgraded.