Wordpress cron wp_schedule_single_event – 操作并不总是有效
Posted
技术标签:
【中文标题】Wordpress cron wp_schedule_single_event – 操作并不总是有效【英文标题】:Wordpress cron wp_schedule_single_event – action not always working 【发布时间】:2020-06-07 23:43:45 【问题描述】:我正在注册一个活动,例如:
wp_schedule_single_event( time(), 'do_custom_hook', array( $body ) );
在此之上,我添加了以下操作:
add_action('do_custom_hook', 'process_custom_hook', 10);
function process_custom_hook($body)
// custom code here
但是,有时 process_custom_hook 函数会触发,而在其他时候,它根本不会触发(不过,它触发的次数最多。大约有 10%-20% 的时间会丢失)
事件总是返回 true,这意味着它必须已经注册。
另外,在测试时,我确保参数(主体)总是不同的。
有什么原因会发生这种情况?
【问题讨论】:
为“现在”安排单个活动的目的是什么?为什么不直接执行process_custom_hook
而不是安排事件呢?此外,您是否真的确保 $body
每次都不同,并且在 10-20% 的情况下不会意外相同?
好的。问题是:这些预定事件并非完全由 cron 守护进程运行。它们在用户查看页面时触发。如果process_custom_hook
包含阻塞代码,无论如何都会在用户尝试加载页面时运行 - 因此,仍然会影响用户的页面加载时间。对于这样的阻塞请求,有两种选择:使用 AJAX,这样用户就不会直接受到处理时间的影响,或者使用真正的 cron 作业调用需要 wp-load.php
的 PHP 文件,然后执行 process_custom_hook
的东西。
根据我的研究 (wordpress.stackexchange.com/questions/141457/…) wp 使用并行请求,不会阻止用户。此外,我使用 sleep() 函数进行的一些测试似乎表明该函数确实是非阻塞的。
根据我的经验,PHP 的 time()
函数并不总是与 Wordpress 同步。当包含在 WP 函数中时,您应该使用 current_time('timestamp')
或 variations thereof
@Jamie_D 感谢您的意见,但不幸的是,这不是问题所在。奇怪的是wp_schedule_single_event
函数返回true,意思是它一定已经被调度了,但是没有运行也没有出现在cron 中。一定有什么东西在告诉它跳过事件......在给定的时间段内是否有可能发出事件的最大次数?或者,是否应该清理事件(即使我只安排一次,并且它们似乎在执行后被自动删除)?
【参考方案1】:
来自the codex:
请注意,如果您将 $args 的唯一值传递给每个已安排的事件,则安排在同名现有事件之后 10 分钟之前发生的事件将被忽略。
如果您的自定义挂钩仅在某些时候有效,那么这可能是一个值得关注的途径。如果您需要立即处理钩子,那么为钩子赋予唯一名称或将唯一值传递给钩子可能是谨慎的做法。
如果您不需要立即执行作业,那么您可以考虑利用wp_next_scheduled()
来确定作业下次运行的时间,并将作业设置为在下一个计划作业之后运行。
同样值得注意的是,如果这个任务背后似乎有一致的逻辑(似乎是这样) - 为什么不将作业信息存储到数据库中并每 5-10 分钟运行一次 cron 作业从数据库中获取任何新工作并处理它们?这将避免需要处理wp_schedule_single_event()
的行为。
【讨论】:
感谢您的回答。有些事情我觉得很奇怪:即使在 10 分钟的时间范围内多次将相同的参数传递给函数似乎也会触发它(几乎总是如此)。因此,我的测试与您发布的法典摘录并不真正匹配。是的,钩子需要立即处理。我将如何为每次执行赋予钩子一个唯一的名称?值得注意的是,参数是键值对,我确保至少有一个值始终不同,但键是相同的。 补充:为了测试,我将另一个参数传递给由 40 个随机字符组成的函数,以检查 args 是否有问题。事实证明,他们不是。该功能有时仍然无法运行... 您可以在将名称传递给wp_schedule_single_event()
之前运行add_action()
,然后在预定事件结束时使用remove_action()
删除该操作,这是一个建议,我最初不确定是否它可以处理不同的请求(或使用 cron 系统),因此可能需要进行更多的研究。
是的,从我的快速测试来看,由于请求的不同,这似乎会导致一些问题。我会尝试进一步挖掘......【参考方案2】:
根据这个实例的官方文档,
除非您为每个计划的事件传递唯一的 $args 值,否则使用相同的操作挂钩将事件安排在现有事件的 10 分钟内发生将被忽略。你已经说过你做了,但也许仔细检查会有所帮助。
这取决于用户何时访问该网站,因此如果预定时间已过,当有人访问您的 WordPress 网站时将触发该操作。
文档还说您可以使用wp_next_scheduled()
来防止重复事件并使用wp_schedule_event()
来安排重复事件。
在某些运行但被忽略的情况下,计划可能会返回 true。所以它确实运行了,但被忽略了。
我建议对发送和接收的所有内容进行详细记录,以便您自己查看所发生的事情是否与您确信的事情相同。
这里有一些包含类似问题和文档的链接,您可以查看。
我希望这会有所帮助。如果没有,我们一起解决。
https://developer.wordpress.org/reference/functions/wp_schedule_single_event/ https://wordpress.stackexchange.com/questions/15475/using-wp-schedule-single-event-with-arguments-to-send-email https://rudrastyh.com/wordpress/wp_schedule_single_event.html http://hookr.io/functions/wp_schedule_single_event/【讨论】:
【参考方案3】:来自Wordpress Document:
WP-Cron 的工作原理是在每次页面加载时检查计划的列表 任务以查看需要运行的内容。由于运行的任何任务都将被调用 在该页面加载期间。
WP-Cron 不会像系统 cron 那样持续运行;它只是 在页面加载时触发。
如果您安排时间,可能会发生安排错误 下午 2:00 的任务,直到下午 5:00 才发生页面加载。
我认为您的 cron 事件可能会错过,因为在预定时间没有发生页面加载。
以下是您的问题的解决方案: Hooking WP-Cron Into the System Task Scheduler
如前所述,WP-Cron 不会连续运行,它可以 如果有必须按时运行的关键任务,这将是一个问题。那里 是一个简单的解决方案。只需设置系统的任务 调度程序以您希望的时间间隔运行(或在特定时间运行 需要)。最简单的解决方案是使用工具发出 Web 请求 到 wp-cron.php 文件...
【讨论】:
【参考方案4】:在我的例子中,这个确切的问题发生在 Woocommerce 的 action scheduler 也在运行时。 Action Scheduler 是 Woocommerce 附带的 cron 任务管理器,还有其他插件,例如 wp-mail-smtp。
我遇到了完全相同的问题,但不知道出了什么问题。我尝试调试 Wordpress 代码,得出的结论是,在每分钟的 10 秒内安排任务(即,将其添加到计划任务的那一刻)时,它会立即被删除。这似乎是某种竞赛条件,动作调度程序只是将其从堆栈中弹出,而普通的 wp cron 无法执行它,因为任务已经消失了。
我还需要说,我已经设置 crontab
每分钟调用 wp-cron.php(而不是 Wordpress 的“假 cron”)。
当我将 wp_schedule_single_event
替换为 Action Scheduler 的 as_enqueue_async_action
函数时,不再丢弃任何任务。
我认为另一种方法是卸载任何使用 Action Scheduler 的东西,但我没有尝试过。
【讨论】:
【参考方案5】:您正在使用 Wordpress 中的 cron,但某些插件会禁用或阻止 CRON 工作。在这种情况下,我的建议是通过 Server Cron 创建此计划,或者安装一个插件来重新确认您的计划。
我遇到了同样的问题,它甚至有点难以找到......而且你会看到它没有最新的更新,但对我来说它有效。 https://wordpress.org/plugins/wp-crontrol & https://br.wordpress.org/plugins/advanced-cron-manager/
您可以确定要编辑的 Cron,从而使您的版本更加精确。还有其他插件可以并且应该与此相关。你提到了 cron 的日程安排。这就是为什么我指出这个。因此,您可以了解日历上的 Chrome 配置。 WP Cron 你可以编辑你的 Cron 时间表
【讨论】:
那就用我放的这个插件作为参考,你就不会再有问题了 插件用于查看 cron 作业活动。他们如何帮助解决我的代码问题?另外,我已经安装了后者。以上是关于Wordpress cron wp_schedule_single_event – 操作并不总是有效的主要内容,如果未能解决你的问题,请参考以下文章