Puncte:1

De ce ar putea uneori un lot inițiat în hook_install() să nu fie procesat?

drapel in

Am două module, module_alpha și module_beta.

Ambele module instalează un tabel de bază de date cu hook_schema() pe care le folosesc pentru a urmări informații despre nodurile publicate. Datele sunt înregistrate în tabel cu metodele de service executate din hook_node_insert() și hook_node_update() cârlige. Toate acestea funcționează.

Dar, trebuie să procesez toate nodurile existente atunci când modulul este instalat pentru a completa tabelele personalizate cu informații despre nodurile deja existente publicate.Fiecare modul implementează hook_install() și utilizează un proces batch pentru a procesa toate nodurile publicate existente. Cu toate acestea, văd inconsecvențe ciudate. Uneori procesul batch se execută, alteori nu. Un scenariu poate funcționa pentru un modul, dar nu pentru celălalt. Toate acestea, chiar dacă codul este aproape identic. Iată scenariile pe care le-am testat:

Metoda de instalare a modulului Modulul Alpha Modul Beta
drush ro MYMODULE Lotul se execută Lotul nu se execută
drush cim Lotul nu se execută Lotul nu se execută
UI, activați modulul din /admin/modules Lotul se execută Lotul se execută
UI, sincronizați configurația din /admin/config/development/configuration Lotul se execută Lotul se execută

Executarea lotului indică faptul că lotul se execută complet conform așteptărilor, cu mesaje de progres, iar tabelul meu este umplut cu date. Lotul nu se execută indică faptul că lotul nu este executat deloc. Nu sunt afișate mesaje de eroare sau în jurnale. Cea mai ciudată parte a acestor date este că drush en module_alpha întotdeauna reușește și drush en module_beta eșuează întotdeauna.

Ce ar putea cauza procesul batch să funcționeze în unele cazuri, dar nu în altele? Cum pot executa în mod consecvent acest proces lot în toate aceste 4 metode, indiferent dacă modulul este activat prin interfață de utilizare sau prin drush? Sincer să fiu, singura metodă pe care o voi folosi este drush cim

Cod:

În MYMODULE.install:

funcția MYMODULE_install() {
  $lot = nou \Drupal\Core\Batch\BatchBuilder();
  $lot
    ->setTitle(t('Procesarea în bloc a articolelor existente.'))
    // Această operație face referire la o funcție diferită per modul.
    // În ambele cazuri, funcția se află în MYMODULE.module și codul este aproape identic.
    ->addOperation('_MYMODULE_initialize_items', []);

  batch_set($batch->toArray());
}

În MYMODULE.module:

funcția _MYMODULE_initialize_items(&$context) {
  $batch_size = 25;
  $entity_type = 'nod';
  // Țintesc pachete diferite în module_alpha și module_beta.
  $bundle = 'MY_TARGET_BUNDLE';

  dacă (!isset($context['sandbox']['processed'])) {
    $context['sandbox']['processed'] = 0;
  }

  dacă (gol ($context['sandbox']['entity_ids'])) {
    $context['sandbox']['entity_ids'] = \Drupal::entityTypeManager()
      ->getStorage($entity_type)
      ->getQuery()
      ->condition('tip', $bundle)
      ->condition('status', 1)
      ->execute();

    dacă (is_array($context['sandbox']['entity_ids'])) {
      $context['sandbox']['total'] = count($context['sandbox']['entity_ids']);
    }
  }

  dacă (!empty($context['sandbox']['entity_ids'])) {
    $current_batch_ids = array_slice($context['sandbox']['entity_ids'], $context['sandbox']['processed'], $batch_size);
    $current_batch_entities = \Drupal::entityTypeManager()
      ->getStorage($entity_type)
      ->loadMultiple($current_batch_ids);

    foreach ($current_batch_entities ca $entity) {
      // Folosesc servicii și metode diferite în module_alpha și module_beta.
      \Drupal::service('MYMODULE.my_service')
        ->processEntity($entity);

      $context['sandbox']['processed']++;
    }
  }

  dacă (!empty($context['sandbox']['total'])) {
    $context['finished'] = $context['sandbox']['processed'] / $context['sandbox']['total'];
    $context['mesaj'] = t('Processate @processed of @total items.', [
      '@processed' => $context['sandbox']['processed'],
      '@total' => $context['sandbox']['total'],
    ]);
  }
  else {
    $context['terminat'] = 1;
  }
}

Exemplu de metodă de serviciu numită în procesul batch:

funcția publică processEntity(EntityInterface $entity) {
  // $this->db este injectat serviciul `@database`, adică \Drupal::service('database');
  returnează $this->db
    ->insert('MYMODULE_mytable')
    ->câmpuri([
      'entity_type' => $entity->getEntityTypeId(),
      'entity_bundle' => $entity->bundle(),
      'entity_uuid' => $entity->uuid(),
      // etc...
    ])
    ->execute();
}
leymannx avatar
drapel ne
Am experimentat ceva similar cu ceva timp în urmă și am găsit puține informații despre DO. Am încercat să creez niște termeni inactivi pe `hook_install`. Acest lucru a funcționat când modulul a fost activat prin interfața de utilizare sau `drush en`. Dar nu a funcționat când modulul a fost activat în timpul „drush cim”. După ce nu am găsit nicio soluție, am mutat logica de la `hook_install` într-un formular personalizat, pentru a fi declanșat manual din UI.
leymannx avatar
drapel ne
Tocmai l-am găsit pe acesta https://www.drupal.org/project/drupal/issues/2906107. Și apoi este acesta https://www.drupal.org/project/currency_taxonomy/issues/3133817. Aceeași problemă.
sonfd avatar
drapel in
Interesant. Ar putea fi aceasta o eroare cu `drush config:import`?
leymannx avatar
drapel ne
Da, asa cred. Ceva e inconsecvent cumva. Și nu a fost încă descurcat. Modulele tale conțin vreo configurație?
sonfd avatar
drapel in
Nu, fără configurare.
sonfd avatar
drapel in
Votez pentru a închide această întrebare pentru că acum cred că aceasta este practic o eroare cu `drush cim`. Cred că cazul meu în care module_beta nu este în loturi cu `drush en` este doar un fel de eroare ciudată de utilizator din partea mea. Aruncă asta și problema este exclusiv cu „drush cim” https://github.com/drush-ops/drush/issues/5105
leymannx avatar
drapel ne
Nu sunt sigur, dar cred că întrebarea ar putea fi ștearsă după ce a fost închisă o perioadă. Poate includeți acel conținut bine documentat al postării în problemă, în loc să faceți doar linkuri aici.
sonfd avatar
drapel in
@leymannx Bun apel. Mulțumesc.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.