วิธีการตรวจสอบให้แน่ใจว่ามีเพียงหนึ่ง wp_cron () เท่านั้นที่ทำงานในเวลา?


9

ฉันมีwp_cron()ฟังก์ชั่นประมาณ 20 อย่างเช่นรหัสต่อไปนี้ crons เกือบทั้งหมดทำงานทุกชั่วโมง ไม่กี่รายวัน

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  //Complex Code
}

เพื่อเพิ่มประสิทธิภาพเซิร์ฟเวอร์และเพื่อไม่ให้ได้รับข้อความ จำกัด เซิร์ฟเวอร์จาก บริษัท โฮสติ้งฉันต้องการให้แน่ใจว่า cron เดียวเท่านั้นที่ทำงานในเวลาที่กำหนด ... เป็นไปได้หรือไม่


คำตอบที่ได้รับการยอมรับในปัจจุบันนั้นยอดเยี่ยม แต่ฉันมีคำถามต่อไปนี้เป็นสาเหตุที่ทำให้ฉันเริ่มรับรางวัลสำหรับคำถามนี้

โปรดอ่านคำตอบที่ยอมรับได้ในตอนแรก

สมมติว่า Cron 1 รันโค้ด cron2 ของฉันจะไม่ทำงานเพราะเรายังอยู่ใน 5 นาทีหรือ cron แรกยังคงทำงานอยู่ แต่เนื่องจากการwp_schedule_event( time(), 'hourly', 'my_task_hook' );ทำงานสำหรับ cron2 ฉันคิดว่า WordPress พิจารณาว่าเป็น cron2 รัน ..... ดังนั้นโดยทั่วไปรหัส ของรหัส cron2 ไม่เคยทำงาน ..... หรือฉันมีความเข้าใจผิดบางอย่าง?


ไม่คุณเข้าใจถูกต้อง ฉันจะอัปเดตคำตอบของฉันด้วยวิธีแก้ปัญหาของคุณ ...
Krzysiek Dróżdż

คำตอบ:


10

ใช่มันเป็นไปได้ ...

และตามจริงแล้วมันสำคัญมากที่จะทำ ... WP Scheduler บางครั้งมีแนวโน้มที่จะทำให้เกิดปัญหาเมื่องาน cron ยาว ...

ดังนั้นฉันจะแก้ปัญหานี้อย่างไร

ฉันใช้Transients APIเพื่อใช้เซมาฟอร์ ...

นี่คือรหัส:

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  // if some other my_task is already running, stop
  if ( get_transient( 'my_task_function_semaphore' ) ) return;

  // set semaphore for 5 minutes
  set_transient( 'my_task_function_semaphore', true, 5*60 );

  // DO YOUR STUFF

  delete_transient( 'my_task_function_semaphore' );
}

เหตุใดฉันจึงใช้การชั่วคราวในกรณีนี้ เพราะ:

  • พวกมันเป็นส่วนหนึ่งของ WP
  • พวกมันใช้งานง่ายและมีประสิทธิภาพ
  • พวกเขาจะไม่ทำให้เกิดการหยุดชะงัก สมมติว่างาน cron ของฉันสามารถถูกฆ่าได้ (ข้อผิดพลาดบางอย่างอาจเกิดขึ้นหรือทำงานนานเกินไปและถูกฆ่าและอื่น ๆ ) ในกรณีเช่นนี้มันจะไม่ลบสัญญาณดังนั้นงานในอนาคตทั้งหมดจะไม่ทำงาน การใช้การชั่วคราวแก้ปัญหานี้เพราะหลังจากเวลาชั่วคราวจะถูกลบ

และถ้ามีการกระทำที่แตกต่างกันมากมายที่ต้องทำ?

ดังนั้นสมมติว่ามีงาน cron ที่แตกต่างกันมากมายที่ไม่ควรทำงานในเวลาเดียวกัน แต่เรายังต้องการให้พวกเขาทั้งหมดทำงาน ...

ถ้าเราใช้วิธีแก้ปัญหาด้วยเซมาฟอร์และใช้เซมาฟอร์เดียวสำหรับงานเหล่านี้ทั้งหมดบางงานอาจไม่ทำงาน แล้วจะทำอย่างไรดี?

ในกรณีเช่นนี้คุณควรเปลี่ยนความคิดของคุณ คุณไม่มีงานอิสระ แต่มีคิวงานที่ต้องทำ ดังนั้นคุณควรใช้มันในวิธีนี้

ดังนั้น:

  1. คุณเพิ่มคิวบางประเภท (คุณสามารถใช้อาร์เรย์และเก็บไว้เป็นตัวเลือกหรือเพิ่มตารางฐานข้อมูลที่กำหนดเอง)
  2. คุณใช้เหตุการณ์ WP cron รายชั่วโมงในปัจจุบันของคุณเพื่อเพิ่มงานในคิว
  3. คุณเพิ่มงาน WP cron ที่สองซึ่งทำงานบ่อยขึ้นและ "กิน" งานจากคิวหนึ่งต่อหนึ่ง งาน "ผู้กิน" นี้ควรใช้เซมาฟอร์เพื่อให้แน่ใจว่ามีเพียงหนึ่งงานที่ทำงานในเวลาเดียวกัน

ขอบคุณ แต่ฉันขอโทษฉันไม่เคยใช้ transient มาก่อน ... แต่ฉันพยายามเข้าใจรหัส ทำไมคุณตั้ง 5 delete_transient()นาทีสำหรับชั่วคราวเพราะคุณลบชั่วคราวโดยใช้ ดังนั้นเวลาที่สำคัญ? ฉันหมายถึงว่าจะให้เวลาไหนไปset_transientมันจะถูกลบหลังจากงานของฉันเสร็จแล้ว ... ทำไมจึงมีเวลา
ฉันเป็นคนที่โง่ที่สุด

เนื่องจากข้อผิดพลาดบางอย่างอาจเกิดขึ้น ลองดูที่สัญลักษณ์แสดงหัวข้อสุดท้าย
Krzysiek Dróżdż

ขอบคุณมาก ... แค่คำถามเดียว อย่างที่ฉันเข้าใจถ้าฉันใช้my_task_function_semaphoreเป็นชื่อชั่วคราวฉันต้องใช้ crons อื่นทั้งหมดในชื่อเดียวกัน
ฉันเป็นคนที่โง่ที่สุด

@IamtheMostStupidPerson มันขึ้นอยู่กับสิ่งที่คุณต้องการที่จะประสบความสำเร็จ ... หากมีเพียงหนึ่งงานที่ควรทำงานในช่วงเวลาที่กำหนดใช่แล้ว - งานทั้งหมดควรใช้ชื่อชั่วคราวเช่นเดียวกับสัญญาณ
Krzysiek Dróżdż

1
ฉันได้ทำสิ่งที่คล้ายกันด้วยเครื่องมือ Job Queue เช่น Gearman การใช้งานนี้อาจช่วยได้: github.com/10up/WP-Minions
Fayaz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.