한 번에 하나의 wp_cron () 만 실행되도록하는 방법은 무엇입니까?


9

wp_cron()다음 코드와 같은 약 20 개의 기능이 있습니다. 거의 모든 크론은 매시간 실행됩니다. 몇 개는 매일입니다.

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 1을 실행한다고 가정 해보십시오. 여전히 우리가 5 분 안에 있거나 첫 cron이 여전히 실행 중이기 때문에 cron2의 코드가 실행되지 않지만 wp_schedule_event( time(), 'hourly', 'my_task_hook' );cron2에 대한 실행으로 인해 WordPress가 cron2 실행으로 간주한다고 생각합니다 ..... 그래서 기본적으로 코드 cron2 코드가 실행되지 않습니다 ..... 또는 뭔가 잘못 이해 했습니까?


아니, 당신은 그것을 올바르게 이해합니다. 문제에 대한 해결책으로 답변을 업데이트하겠습니다 ...
Krzysiek Dróżdż

답변:


10

예, 가능합니다 ...

그리고 솔직히 말해서, 종종 이렇게하는 것이 매우 중요합니다 ... WP 스케줄러는 종종 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. 어떤 종류의 대기열을 추가합니다 (배열을 사용하여 옵션으로 저장하거나 사용자 지정 DB 테이블을 추가 할 수 있음).
  2. 현재 WP cron 시간별 이벤트를 사용하여 작업을 대기열에 추가합니다.
  3. 훨씬 자주 실행되는 두 번째 WP cron 태스크를 추가하고 큐에서 태스크를 하나씩 "먹습니다". 이 "eater"작업은 세마포어를 사용하여 한 번에 하나의 작업 만 실행되도록해야합니다.

고맙지 만 죄송합니다. 이전에 과도를 사용한 적이 없습니다 ... 그러나 코드를 이해하기 위해 노력하고 있습니다. 왜 당신이 사용 과도를 삭제하기 때문에 당신이 과도 5 분으로 설정했다 delete_transient(). 그래서 그 시간이 중요합니까? 나는 당신이 어느 때를 넣었 set_transient는지, 내 일이 끝난 직후에 삭제 된다는 것을 의미 합니다 ... 왜 시간이 있습니까?
나는 가장 바보 같은 사람

약간의 오차가 생기는 경우가 있습니다. 마지막 글 머리 기호를보십시오.
Krzysiek Dróżdż

고마워, 좋아 ... 질문 하나만. 알다시피, my_task_function_semaphore임시 이름으로 사용하는 경우 다른 모든 크론을 같은 이름으로 사용해야합니까?
나는 가장 바보 같은 사람

@IamtheMostStupidPerson 그것은 당신이 달성하고자하는 것에 달려 있습니다 ... 주어진 순간에 하나의 작업 만 작동해야한다면, 그렇습니다-모든 작업은 세마포어와 동일한 일시적 이름을 사용해야합니다
Krzysiek Dróżdż

1
Gearman과 같은 Job Queue 도구를 사용하여 비슷한 작업을 수행했습니다. 이 구현은 다음과 같이 도움이 될 수 있습니다. github.com/10up/WP-Minions
Fayaz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.