如何确保一次只运行一个wp_cron()?


9

我有大约20个wp_cron()函数,例如以下代码。几乎所有的老太婆每小时都跑一次;每天有几个。

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代码永远不会运行.....或者我误会了什么?


不,您正确理解。我将为您的问题提供一些解决方案,以更新我的答案...
KrzysiekDróżdż

Answers:


10

是的,有可能...

老实说,执行此操作通常非常重要...当cron任务很长时,WP Scheduler有时会引起问题...

那么我该如何解决这个问题呢?

我使用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任务,该任务运行频率更高,并且可以“逐个”吃掉队列中的任务。此“吃者”任务应使用信号量以确保一次仅运行一个任务。

谢谢,但是很抱歉,我以前从未使用过瞬变法。。。但是我很想了解代码。为什么您将瞬态设置为5分钟,因为您使用删除了瞬态delete_transient()。那时间很重要吗?我的意思是,无论您输入哪个时间set_transient,在我完成工作后都会将其删除...那么为什么会有时间?
我是最愚蠢的人

因为可能会发生一些错误。看一下最后一个要点。
KrzysiekDróżdż

谢谢,太好了,只是一个问题。据我了解,如果我将my_task_function_semaphore其用作瞬变的名称,那么我是否必须将所有其他克朗使用相同的名称?
我是最愚蠢的人

@IamtheMostStupidPerson取决于您要实现的目标...如果在给定的时间内仅一项任务可以工作,那么可以-所有任务都应使用与信号量相同的临时名称
KrzysiekDróżdż

1
我已经使用Gearman等Job Queue工具完成了类似的工作。此实现可能会有帮助:github.com/10up/WP-Minions
Fayaz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.