Come funziona l'API batch internamente?


19

Ho riscontrato un problema di timeout durante la migrazione dell'altro giorno e ho iniziato a chiedermi come funziona l' API Batch internamente.

Il modo in cui lo capisco è che nella sua forma più semplice passerai una matrice di valori (nid per esempio) e una funzione per operare su quei valori. L'API batch quindi elabora un numero fisso di tali valori con ogni richiesta fino al termine.

Quando un batch è in esecuzione, la pagina sembra utilizzare le richieste Ajax per mostrare l'avanzamento dell'operazione batch (% fatto e messaggi). Presumo che aspetti fino al termine della richiesta per aggiornare l'avanzamento e quindi avviare la richiesta successiva immediatamente dopo?

Se la pagina con la richiesta batch è chiusa, l'elaborazione batch si interrompe? Si riavvierà quando si riapre lo stesso URL? Il modulo di migrazione a volte continua ma probabilmente sta usando le code?

Risposte:


40

Ecco come funziona il batch (in base alla mia comprensione)

1. Inizializza

  1. Inizializza l'elaborazione batch. In base alla configurazione dei client (browser) sull'abilitazione o meno di JavaScript.
  2. I client abilitati per JavaScript sono identificati dal cookie 'has_js' impostato in drupal.js. Se non è stata visitata alcuna pagina abilitata per JavaScript durante la sessione del browser dell'utente corrente, viene restituita la versione non JavaScript.
  3. Se Abilita Javascript usi batch ajax richiedere al mantenere la connessione attraverso la richiesta.
  4. Se JavaScript non è abilitato, Batch utilizza imposta un meta tag in html per effettuare intervalli di aggiornamento regolari per mantenere attiva la connessione attraverso la richiesta.

(Questo è il modo in cui la barra di avanzamento viene aggiornata sull'avanzamento del lavoro completato.)

Processo batch

  1. Per avviare il processo, Batch crea una coda e aggiunge tutte le operazioni (funzioni e argomenti) definite nell'array batch come,

    $batch = array (
    'operations' => array(
      array('batch_example_process', array($options1, $options2)),
      array('batch_example_process', array($options3, $options4)),
      ),
    'finished' => 'batch_example_finished',
    'title' => t('Processing Example Batch'),
    'init_message' => t('Example Batch is starting.'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('Example Batch has encountered an error.'),
    'file' => drupal_get_path('module', 'batch_example') . '/batch_example.inc',
    );

    Inoltre assegna anche un ID batch univoco tra i batch.

  2. Ora le chiamate Batch rivendicano gli elementi della coda uno alla volta ed eseguono la funzione definita con gli argomenti in essa definiti.

  3. Questa è una parte cruciale, La funzione (Operazione) che implementa l'operazione batch dovrebbe bloccare i dati ed elaborare i dati in modo molto efficiente tenendo presente il limite di memoria di PHP, Time out . In caso contrario, si verificherà il problema.

Ho riscontrato un problema di timeout utilizzando migrate l'altro giorno e ho iniziato a chiedermi come funziona l'API batch internamente.

La funzione batch

Le funzioni che implementano Batch dovrebbero prendere molto attentamente le seguenti cose,

  • Numero di articoli all'interno delle operazioni da elaborare come,

    if (!isset($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_node'] = 0;
    $context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));
    }
  • Limitare il numero di elementi da elaborare in una chiamata di funzione come l'impostazione di un limite,

    // For this example, we decide that we can safely process 5 nodes at a time without a timeout.
    $limit = 5;
  • Aggiornamento sul processo di post-elaborazione come,

    // Update our progress information.
        $context['sandbox']['progress']++;
        $context['sandbox']['current_node'] = $node->nid;
        $context['message'] = t('Now processing %node', array('%node' => $node->title));
  • Informare il motore di Batch se il Batch è stato completato o meno,

    // Inform the batch engine that we are not finished,
    // and provide an estimation of the completion level we reached.
    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
      $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     }

La maggior parte dei punti di cui sopra sono curati dalle operazioni batch del Drupal se viene perso nella funzione di implementazione. Ma è sempre meglio definire nella funzione di implementazione

Richiamo terminato in batch

  • Questa è l'ultima richiamata chiamata quando definita nell'array batch Di solito un rapporto di quanto elaborato ecc ...

RISPOSTE

Se la pagina con la richiesta batch è chiusa, l'elaborazione batch si interrompe? Si riavvierà quando lo stesso URL viene riaperto? Il modulo di migrazione a volte continua ma probabilmente sta usando le code?

Sì, idealmente dovrebbe riavviare il batch e, come detto sopra, si basa sulla funzione implementata.

Per risolvere il tuo problema di timeout PHP usa Drush batch che è disponibile nel modulo di migrazione, ma prima di tutto scava le funzioni batch di migrate e prova a dividere i tuoi dati di elaborazione.


1
Passeggiata eccezionale. Vorrei anche sottolineare che il batch inizia l'elaborazione durante quella che, almeno per l'utente, sembra essere "l'inizializzazione". schermo. Cioè, se l'installazione richiede 4 secondi e 10 secondi per elaborare il primo articolo batch, l'utente vedrà il processo "Inizializzazione". per quattordici secondi in questo esempio. Questo ha senso perché il primo messaggio sullo schermo non init è "n completato", che funzionerebbe solo dopo che alcuni sono stati elaborati. Se questo è sbagliato, per favore correggimi!
texas-bronius,

Inoltre, dalla mia esperienza. Se si lascia la pagina l'operazione batch / blocco in corso consumerà comunque risorse fino al completamento. Non avvia più il processo batch ma completa quello corrente.
Elijah Lynn,

10

Se la pagina con la richiesta batch è chiusa, l'elaborazione batch si interrompe?

Sì, verrà interrotto.

Si riavvierà quando lo stesso URL viene riaperto? Il modulo di migrazione a volte continua ma probabilmente sta usando le code?

Come ha detto Dinesh, dipende dall'implementazione.

Dovresti eseguire la migrazione usando drush, perché

Drush viene eseguito dalla riga di comando e non è soggetto a limiti di tempo (in particolare, max_execution_time di PHP non si applica). Quindi, quando si avvia un processo di migrazione in esecuzione tramite Drush, si avvia semplicemente e continua fino a quando non viene completato.

Quando si eseguono processi attraverso un'interfaccia Web, si applica il PH_ max_execution_time (in genere 30 secondi se non inferiore). Pertanto, per i processi di lunga durata è necessario utilizzare l'API Batch, che gestisce la suddivisione di un processo su più richieste. Quindi, un processo di migrazione verrà avviato, eseguito per circa 25 secondi, quindi si fermerà e consentirà all'API Batch di inviare una nuova richiesta di pagina, in cui il processo di migrazione viene riavviato all'infinito.

Quindi, capendolo, perché Drush è meglio?

È più veloce

L'API Batch introduce un sacco di sovraccarico: chiudendo e reinvocando le richieste di pagina, il processo di migrazione deve eseguire di nuovo tutti i costruttori necessari, ristabilire le connessioni al database e rieseguire le query, ecc. E, per un'importazione parziale, deve scegliere da dove era stato interrotto: se i primi 500 record di origine sono stati importati, deve trovare il 501 ° record. A seconda del formato della sorgente e della sua costruzione, ciò può essere ridimensionato o meno: se si utilizzano i segni di alta quota con una sorgente SQL, la query stessa può eliminare i record precedenti e iniziare da dove era stata interrotta. In caso contrario, Migrate deve scorrere i dati di origine alla ricerca del primo record non importato. Con, diciamo, un grande file XML come sorgente,

È più affidabile

L'esecuzione delle migrazioni tramite il browser aggiunge il desktop e la connessione Internet locale come punti di errore. Un errore di rete quando l'API Batch si sposta alla richiesta di pagina successiva, un arresto anomalo del browser, una chiusura accidentale della scheda o della finestra errata possono interrompere la migrazione. L'esecuzione in modalità Drush riduce le parti mobili, eliminando la connessione desktop e Internet locale come fattori.

È più utile

Se qualcosa va storto durante l'esecuzione in Drush, se ci sono messaggi di errore utili li vedrai. Gli errori che utilizzano l'API Batch vengono spesso inghiottiti e tutto ciò che si vede è completamente inutile "Una richiesta HTTP AJAX è terminata in modo anomalo. Segue l'informazione di debug. Percorso: / batch? Id = 901 & op = do StatusText: ResponseText: ReadyState: 4".

Puoi trovare maggiori informazioni su questo qui .

Nel frattempo, se si desidera eseguire il batch anche se la finestra del browser è chiusa, considerare il modulo Processo in background . Ha un batch di sfondo sottomodulo che fa il trucco.

Questo modulo prende in carico l'API Batch esistente ed esegue i processi batch in un processo in background. Ciò significa che se si lascia la pagina batch, i lavori continuano e è possibile tornare all'indicatore di avanzamento in un secondo momento.


wow, usare drush per migrare ha fatto un enorme miglioramento. Devo migrare su un sito live e questo carica molto meno sistema! Grazie!
Uwe

0

Comprendi attentamente l' API Batch e questi moduli ti aiuteranno a:

1- Progers Questo è un tentativo di implementare un framework generico per tenere traccia di ogni progresso

2- L' avanzamento in background assume l'API batch esistente ed esegue i processi batch in un processo in background

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.