Score:1

เหตุใดแบทช์ที่เริ่มต้นใน hook_install() จึงไม่สามารถประมวลผลได้ในบางครั้ง

ธง in

ฉันมีสองโมดูล module_alpha และ module_beta

ทั้งสองโมดูลติดตั้งตารางฐานข้อมูลด้วย hook_schema() ซึ่งใช้ในการติดตามข้อมูลเกี่ยวกับโหนดที่เผยแพร่ ข้อมูลถูกบันทึกในตารางด้วยวิธีการบริการที่ดำเนินการจาก hook_node_insert() และ hook_node_update() ตะขอ ทั้งหมดนี้ใช้งานได้

แต่ฉันต้องประมวลผลโหนดที่มีอยู่ทั้งหมดเมื่อติดตั้งโมดูลเพื่อทดแทนตารางที่กำหนดเองด้วยข้อมูลเกี่ยวกับโหนดที่เผยแพร่ที่มีอยู่แล้วแต่ละโมดูลดำเนินการ hook_install() และใช้กระบวนการแบบแบตช์เพื่อประมวลผลโหนดที่เผยแพร่ที่มีอยู่ทั้งหมด อย่างไรก็ตาม ฉันเห็นความไม่ลงรอยกันแปลกๆ บางครั้งกระบวนการแบทช์ดำเนินการ บางครั้งก็ไม่ทำงาน สถานการณ์จำลองอาจใช้ได้กับโมดูลหนึ่ง แต่โมดูลอื่นใช้ไม่ได้ ทั้งหมดนี้แม้ว่ารหัสจะเหมือนกันเกือบทั้งหมด นี่คือสถานการณ์ที่ฉันได้ทดสอบ:

วิธีการติดตั้งโมดูล โมดูลอัลฟ่า โมดูลเบต้า
drush ใน MYMODULE ชุดดำเนินการ ชุดงานไม่ดำเนินการ
ซิม ชุดงานไม่ดำเนินการ ชุดงานไม่ดำเนินการ
UI เปิดใช้งานโมดูลจาก /admin/modules ชุดดำเนินการ ชุดดำเนินการ
UI, ซิงค์การกำหนดค่าจาก /admin/config/development/configuration ชุดดำเนินการ ชุดดำเนินการ

การดำเนินการเป็นชุดบ่งชี้ว่าชุดดำเนินการอย่างสมบูรณ์ตามที่คาดไว้ พร้อมข้อความแสดงความคืบหน้า และตารางของฉันเต็มไปด้วยข้อมูล แบทช์ไม่ดำเนินการ บ่งชี้ว่าแบทช์ไม่ถูกดำเนินการเลย ไม่มีข้อความแสดงข้อผิดพลาดแสดงหรือในบันทึก ส่วนที่แปลกประหลาดที่สุดเกี่ยวกับข้อมูลนี้คือ drush และ module_alpha ประสบความสำเร็จเสมอและ drush และ module_beta ล้มเหลวเสมอ

อะไรเป็นสาเหตุให้กระบวนการแบทช์ทำงานได้ในบางกรณี แต่ไม่ใช่ในบางกรณี ฉันจะดำเนินการกระบวนการแบทช์นี้อย่างสม่ำเสมอในทั้ง 4 วิธีเหล่านี้ได้อย่างไร ไม่ว่าจะเปิดใช้งานโมดูลผ่าน UI หรือ drush พูดตามตรง วิธีเดียวที่ฉันจะใช้คือ ซิม

รหัส:

ใน MYMODULE.install:

ฟังก์ชัน MYMODULE_install() {
  $batch = ใหม่ \Drupal\Core\Batch\BatchBuilder();
  $แบทช์
    ->setTitle(t('กำลังประมวลผลรายการที่มีอยู่จำนวนมาก'))
    // การดำเนินการนี้อ้างอิงถึงฟังก์ชันที่แตกต่างกันในแต่ละโมดูล
    // ในทั้งสองกรณี ฟังก์ชันจะอยู่ใน MYMODULE.module และโค้ดเกือบจะเหมือนกัน
    ->addOperation('_MYMODULE_initialize_items', []);

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

ใน MYMODULE.module:

ฟังก์ชัน _MYMODULE_initialize_items(&$บริบท) {
  $batch_size = 25;
  $entity_type = 'โหนด';
  // ฉันกำหนดเป้าหมายบันเดิลที่แตกต่างกันใน module_alpha และ module_beta
  $มัด = 'MY_TARGET_BUNDLE';

  ถ้า (!isset($context['sandbox']['ประมวลผล'])) {
    $context['sandbox']['ประมวลผลแล้ว'] = 0;
  }

  ถ้า (ว่าง ($context['sandbox']['entity_ids'])) {
    $context['sandbox']['entity_ids'] = \Drupal::entityTypeManager()
      ->getStorage($entity_type)
      ->getQuery()
      ->condition('ประเภท', $bundle)
      ->เงื่อนไข ('สถานะ', 1)
      ->ดำเนินการ ();

    ถ้า (is_array($context['sandbox']['entity_ids'])) {
      $context['sandbox']['total'] = count($context['sandbox']['entity_ids']);
    }
  }

  ถ้า (!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 เป็น $entity) {
      // ฉันใช้บริการและวิธีการอื่นใน module_alpha และ module_beta
      \Drupal::service('MYMODULE.my_service')
        ->processEntity($เอนทิตี);

      $context['sandbox']['ประมวลผล']++;
    }
  }

  ถ้า (!empty($context['sandbox']['total'])) {
    $context['finished'] = $context['sandbox']['processed'] / $context['sandbox']['total'];
    $context['message'] = t('ประมวลผล @ประมวลผล จาก @total items.', [
      '@processed' => $context['sandbox']['ประมวลผล'],
      '@total' => $context['sandbox']['total'],
    ]);
  }
  อื่น {
    $context['เสร็จสิ้น'] = 1;
  }
}

ตัวอย่างวิธีการบริการที่เรียกใช้ในกระบวนการแบทช์:

ฟังก์ชั่นสาธารณะ processEntity (EntityInterface $entity) {
  // $this->db ถูกฉีดบริการ `@database` เช่น \Drupal::service('database');
  ส่งคืน $this->db
    ->แทรก('MYMODULE_mytable')
    ->ฟิลด์ ([
      'entity_type' => $entity->getEntityTypeId(),
      'entity_bundle' => $entity->bundle(),
      'entity_uuid' => $entity->uuid(),
      // ฯลฯ...
    ])
    ->ดำเนินการ ();
}
leymannx avatar
ne flag
ฉันพบสิ่งที่คล้ายกันเมื่อไม่นานมานี้และพบข้อมูลเล็กน้อยเกี่ยวกับ DO ฉันพยายามสร้างคำศัพท์จำลองใน `hook_install` สิ่งนี้ใช้ได้เมื่อเปิดใช้งานโมดูลผ่าน UI หรือ `drush en` แต่มันใช้งานไม่ได้เมื่อเปิดใช้งานโมดูลระหว่าง `drush cim` หลังจากไม่พบวิธีแก้ไข ฉันย้ายตรรกะจาก `hook_install` ไปเป็นรูปแบบที่กำหนดเองในตอนท้าย เพื่อให้ถูกเรียกใช้ด้วยตนเองจาก UI
leymannx avatar
ne flag
เพิ่งพบอันนี้ https://www.drupal.org/project/drupal/issues/2906107 แล้วก็มีอันนี้ https://www.drupal.org/project/currency_taxonomy/issues/3133817 ปัญหาเดียวกัน.
sonfd avatar
in flag
น่าสนใจ. นี่อาจเป็นข้อผิดพลาดกับ `drush config: import` หรือไม่
leymannx avatar
ne flag
ใช่ฉันก็คิดเช่นนั้น. มีบางอย่างที่ไม่สอดคล้องกัน และยังไม่ได้แก้ โมดูลของคุณมีการกำหนดค่าหรือไม่?
sonfd avatar
in flag
ไม่ ไม่มีการกำหนดค่า
sonfd avatar
in flag
ฉันลงคะแนนให้ปิดคำถามนี้เพราะตอนนี้ฉันคิดว่านี่เป็นข้อบกพร่องของ `drush cim` ฉันคิดว่ากรณีของฉันที่ module_beta ไม่แบทช์ด้วย `drush en` เป็นเพียงข้อผิดพลาดของผู้ใช้แปลก ๆ ในส่วนของฉัน โยนมันออกไปและปัญหาอยู่ที่ `drush cim` เท่านั้น https://github.com/drush-ops/drush/issues/5105
leymannx avatar
ne flag
ไม่แน่ใจ แต่ฉันคิดว่าคำถามอาจถูกลบหลังจากถูกปิดไประยะหนึ่ง อาจนำเนื้อหาโพสต์ที่มีการจัดทำเป็นเอกสารมาอย่างดีในประเด็นนี้แทนการลิงก์เฉพาะที่นี่
sonfd avatar
in flag
@leymannx โทรได้ดี ขอขอบคุณ.

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา