Jump to content
MediaWiki

Příručka:Fronta úloh/Pro vývojáře

From mediawiki.org
This page is a translated version of the page Manual:Job queue/For developers and the translation is 100% complete.
Languages:

Úkoly nejsou naléhavé. Obecný úvod a správu front úloh naleznete v článku Fronta úloh .

Odložené aktualizace

Odložené aktualizace (nebo odložitelné aktualizace) jsou užitečným způsobem, jak odložit časově náročné úkoly, aby se urychlila hlavní odpověď MediaWiki. Použití těchto rozhraní naleznete v článku API třídy DeferredUpdates a Databázové transakce .

Odložené aktualizace jsou reprezentovány jako volatelné funkce, které zařadíme do fronty v poli a poté zavoláme na konci PHP procesu MediaWiki. Volání obvykle proběhne po dokončení odpovědi na webový požadavek (např. echo a načtení všeho do prohlížeče), ale před skutečným ukončením nebo návratem na webový server. Toto je interně zapnuto fastcgi_finish_request() v MediaWiki::doPostOutputShutdown() .

Odložitelné aktualizace se provádějí na konci aktuálního procesu. Jsou ukládány pouze v rámci stejného webového požadavku (nebo jiného procesu, jako jsou například skripty údržby CLI).

To se liší od úloh, které jsou plánovány prostřednictvím perzistentního úložiště a následně spuštěny o několik minut nebo hodin později, nezávisle na původním požadavku, který úlohu zařadil do fronty, a po něm. Fronta úloh v MediaWiki je plug-in služba. Výchozí backend přidává úlohy do tabulky job v hlavní databázi wiki. Výchozí spouštěč úloh spustí až jednu úlohu na konci náhodných zobrazení stránek.

Další informace:

Který použít?

Odložitelné aktualizace by se měly používat pro úlohy, jejichž dokončení obvykle trvá jen několik milisekund, aby se urychlila odezva webu. Vzhledem k povaze odložení to znamená, že selhání je před klienty skryto, protože odpověď již byla odeslána.

Normální režim

Příklady kritických úloh, které nespouštíme prostřednictvím odložených aktualizací. Uživatelé musí být o selhání informováni a obecněji by lidé měli vědět, jak a kdy byla jejich akce dokončena, aby mohli dále jednat s vědomím, že změna byla dokončena. Např. provádět další úpravy, které závisí na předchozích, případně skriptované nebo dávkově automatizované.

  • Zápis do databáze, který vytvoří stránku nebo uloží úpravu.
  • Vytvořit účet, změnit heslo.
  • Explicitní funkce "odeslat e-mail".

Odložená aktualizace

Příklady "naléhavých" úkolů, které spouštíme prostřednictvím odložených aktualizací po odpovědi po uložení úpravy. Očekává se, že tyto malé transakce se projeví, pokud je klient následně vyhledá, ale jejich výsledek není nutný k vykreslení odpovědi na samotnou úpravu.

  • Aktualizace metadat, která přidá článek do určité kategorie.
  • Publikování události úpravy do kanálu Poslední změny .
  • Aktualizace pole účtu user_editcount .

Fronta úloh

Příklady "neurgentních" úkolů, které spouštíme prostřednictvím fronty úloh:

  • Po uložení úpravy do šablony projděte potenciálně miliony dotčených stránek, abyste je znovu analyzovali a odstranili (tzv. "Obnovit odkazy" neboli LinksUpdate).
  • Pravidelně zmenšujte staré řádky od hodnoty Databázová tabulka recentchanges .
  • Po nahrání fotografie předem vykreslete běžné velikosti miniatur.
  • Po uložení úpravy článku odešlete e-maily účtům, které sledují tuto stránku a mají zapnutá e-mailová oznámení.

Použijte jobs, pokud potřebujete ukládat data v kontextu požadavku GET

Z důvodů škálovatelnosti a výkonu by vývojáři MediaWiki obecně neměli provádět zápisy do databáze během prohlížení stránek nebo jiných GET požadavků. Pokud se tomu stane obtížné se vyhnout, nejprve si přečtěte Pokyny pro výkon backendu a zvažte, zda se nepodívat na radu od jiných vývojářů nebo týmu pro výkon, jak k problému přistupovat jiným způsobem.

Upozorňujeme, že velké wiki farmy (například Wikimedia) mohou fungovat z více datových center, a proto mohou spouštět požadavky za GET (které neočekávají zápisy do databáze) ze sekundárního datového centra, které by mělo být schopno na takové požadavky reagovat, aniž by se spoléhalo na komunikaci s primárním datovým centrem.

Pokud si jste dostatečně jisti, že vaše funkce během požadavku GET jen zřídka zjistí potřebu zápisu do databáze a pokud zápis není urgentní, pak jednou z možností, kterou máte, je zařadit úlohu do fronty během požadavku GET. Fronty úloh lze asynchronně ukládat do vyrovnávací paměti a synchronizovat napříč datovými centry, a proto nevyžadují okamžitou komunikaci mezi řadiči domény. Pak se můžete spolehnout na to, že úloha bude nakonec přenesena na primární řadič domény, kde se pak v budoucnu spustí.

Odložené aktualizace by se neměly používat k provádění zápisů do databáze po požadavku GET. Pokus o to bude zaznamenán varovný signál DBPerformance.

Odložená záložní aktualizace

Odložitelné aktualizace si mohou zvolit implementaci rozhraní EnqueueableDataUpdate . Takové aktualizace lze podle potřeby automaticky převést na úlohu. Například pokud se aktualizace nezdaří, MediaWiki ji převede na úlohu a zařadí ji do fronty pro pozdější opakování. Existují i ​​další situace, kdy zlepšujeme spolehlivost nebo optimalizujeme propustnost tím, že proaktivně převádíme aktualizace na úlohy, kdekoli je to možné.

Protože jakýkoli kód MediaWiki může zařazovat odložené aktualizace do fronty, je také možné, aby skript nebo úloha údržby CLI implicitně vytvořila seznam odložených aktualizací. Pokud tyto dávkové operace nakonec zařadí do fronty mnoho aktualizací, MediaWiki proaktivně převede úkoly na úlohy, kdekoli je to možné (o to interně postará třída DeferredUpdates).

Registrace úlohy

Chcete-li použít frontu úloh k provedení neurgentních úkolů, musíte provést tyto kroky:

Vytvořit podtřídu Job

Musíte vytvořit třídu, která bude provádět vaše odložené aktualizace:

<?php
namespace MediaWiki\Extension\MyExt\Job\SomeExpensiveOperationJob;
use MediaWiki\JobQueue\Job;
use Wikimedia\Rdbms\IConnectionProvider;
class SomeExpensiveOperationJob extends Job {
	private IConnectionProvider $dbProvider;
	public function __construct(
		array $params,
		IConnectionProvider $dbProvider
	) {
		// Nahraďte SomeExpensiveOperationJob identifikátorem vaší úlohy.
		parent::__construct( 'SomeExpensiveOperationJob', $params );
		$this->dbProvider = $dbProvider;
	}
	/**
	 * @inheritDoc
	 */
	public function run() {
		$dbw = $this->dbProvider->getPrimaryDatabase();
		$update = $dbw->newUpdateQueryBuilder()
			->update( 'mytable' )
			->set( [
				'foo' => $this->params['foo'],
				'bar' => $this->params['bar'],
			] )
			->caller( __METHOD__ );
		$update->execute();
		return true;
	}
}

Přidejte svou třídu Job do globálního seznamu

Přidejte třídu Job do globálního pole $wgJobClasses . V rozšířeních se to dělá v souboru extension.json a v jádru v souboru DefaultSettings.php. Klíč musí být jedinečný a musí odpovídat hodnotě v konstruktoru úlohy a hodnota je název třídy. Takže v tomto příkladu by to vypadalo takto:

{
"JobClasses":{
"SomeExpensiveOperationJob":{
"class":"MediaWiki\\Extension\\MyExt\\Job\\SomeExpensiveOperationJob",
"services":[
"ConnectionProvider"
]
}
}
}

Jak zařadit úlohu do fronty

<?php
/**
 * 1. Access the JobQueueGroup for the current wiki
 *
 * Pro MW 1.36 a starší volejte místo toho JobQueueGroup::singleton().
 */
$services = MediaWikiServices::getInstance();
$jobQueueGroup = $services->getJobQueueGroupFactory()->makeJobQueueGroup();
/**
 * 2. Vytvořte objekt Job
 *
 * Vytvořte podtřídu a předejte jí příslušné parametry.
 *
 * These will be available as $this->params in your Job class when it executes later.
 *
 * Některé starší úlohy vyžadují parametr $title, i když ho interně ignorují.
 * V tom případě můžete přejít na TitleFactory->newMainPage().
 */
$titleFactory = $services->getTitleFactory();
$title = $titleFactory->newFromText( 'User:Example/Foobar' ); // or $example->getTitle()
$job = new MyDataJob( $title, [
 'example' => true,
 'mydata' => [ 'x' ],
] );
/**
 * 3. Zařaďte úlohu do fronty
 */
$jobQueueGroup->lazyPush( $job );

Zařazení do fronty pomocí JobQueueGroup::lazyPush() umožňuje MediaWiki odeslat úlohu dávkově spolu s dalšími úlohami ve frontě na konci webové odpovědi. Pokud je řazení do fronty neoddělitelné od hlavního účelu vašeho požadavku a chcete, aby jakékoli selhání řazení do fronty vedlo (například) k vrácení všech zápisů do databáze a zobrazení chybové stránky uživateli, zvažte místo toho volání JobQueueGroup::push() .

Ostatní

Typ fronty úloh

Typ fronty úloh je název příkazu, který přiřadíte metodě parent::__construct() vaší třídy úloh. Např. s použitím výše uvedeného příkladu by to bylo synchroniseThreadArticleData.

getQueueSizes()

JobQueueGroup->getQueueSizes() vrátí pole všech typů front úloh a jejich velikostí.

Array
(
 [refreshLinks] => 1
 [refreshLinks2] => 3
 [synchroniseThreadArticleData] => 10
)

getSize()

I když je hodnota getQueueSizes() užitečná pro analýzu celé fronty úloh, z důvodu výkonu je nejlepší použít hodnotu JobQueueGroup->get( /* <job type> */ )->getSize() při analýze konkrétního typu úlohy, která vrátí pouze velikost fronty úloh pro daný typ úlohy.

Array
(
 [synchroniseThreadArticleData] => 100
)

Vnitřní části

Odesílání úloh

Primární funkcí je JobQueueGroup::push(). Vybere frontu úloh odpovídající typu úlohy a v závislosti na implementaci fronty úloh (databáze nebo Redis) bude úloha odeslána buď prostřednictvím připojení Redis (případ Redis), nebo jako odložitelná aktualizace (případ databáze).

Funkce lazy push (JobQueueGroup::lazyPush()) uchovává úlohy v paměti. Na konci aktuálního provádění (konec požadavku MediaWiki nebo konec aktuálního provádění úlohy) jsou úlohy uložené v paměti odeslány jako poslední odložitelná aktualizace (typu AutoCommitUpdate ). Jako odložitelná aktualizace jsou úlohy odeslány na konci aktuálního provádění a jako AutoCommitUpdate jsou úlohy odeslány jako jedna databázová transakce. Podrobnosti viz JobQueueGroup::lazyPush() a JobQueueGroup::pushLazyJobs().

V CLI si všimněte, že odložitelné aktualizace (buď z JobQueueGroup::push() (implementace JobQueueDB) nebo JobQueueGroup::lazyPush()) se provedou přímo, pokud je příznak transakce databáze (LBFactory::hasTransactionRound() ) volný. Podrobnosti viz DeferredUpdates::addUpdates() a DeferredUpdates::tryOpportunisticExecute().

Když jsou některé úlohy odeslány přes JobQueueGroup::lazyPush(), ale nikdy skutečně neodešly (a proto se ztratí), obvykle kvůli vyvolání neošetřené výjimky, destruktor JobQueueGroup zobrazí v debug logu varování:

PHP Notice: JobQueueGroup::__destruct: 1 buffered job(s) never inserted

Příklad takového varování naleznete v článku T100085. Toto platilo před vydáním MediaWiki 1.29 pro úlohy spouštěné na webu, protože když úloha interně odešle úlohu pomocí pomalu odeslaného příkazu a předchozí úloha je spuštěna v části požadavku MediaWiki týkající se ukončení, pozdější úloha není odeslána (protože již byla volána funkce JobQueueGroup::pushLazyJobs()). Opravou této konkrétní chyby bylo volání funkce JobQueueGroup::lazyPush() v funkci JobRunner::executeJob(), aby se úlohy s pomalu odeslaným příkazem vždy odeslaly po provedení každé úlohy.

Provádění úloh

Úlohy se obvykle provádějí na konci webového požadavku, a to $wgJobRunRate na požadavek. Pokud je hodnota $wgJobRunRate == 0, na konci webového požadavku se nespustí žádné úlohy. Výchozí hodnota $wgJobRunRate je 1.

Všechny úlohy zařazené do fronty lze kdykoli spustit spuštěním příkazu maintenance/runJobs.php. To je obzvláště důležité, když je to $wgJobRunRate == 0.

Úlohy provozuje třída JobRunner. Každé úloze je přiřazena vlastní databázová transakce.

Na konci provádění úlohy se provedou odložitelné aktualizace. Od verze MediaWiki 1.28.3/1.29 jsou úlohy s pomalu odesílaným procesem odkládány pomocí odložitelné aktualizace, aby mohly být použity vyhrazené transakce databáze (s hodnotou AutoCommitUpdate).

Nastavení
Zavádění
Body rozšíření
Obecné
Stránky
Obsah
Značky wiki
Ulehčení
Přihlášení
Osvědčené postupy
Nástroje

AltStyle によって変換されたページ (->オリジナル) /