a5hleyrich/wp-background-processing

WP Background Processing 可以用来执行非阻塞异步请求,或者作为后台处理工具,允许您排队任务。

1.3.1 2024-02-28 13:39 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:26:20 UTC


README

WP Background Processing 可以用来执行非阻塞异步请求,或者作为后台处理工具,允许您排队任务。查看示例插件或阅读相关文章

TechCrunch WP Asynchronous Tasks启发。

需要 PHP 5.6+

安装

在项目中安装此库的推荐方法是通过Composer加载

composer require deliciousbrains/wp-background-processing

强烈建议使用Mozart包给库类文件添加前缀,以防止与其他使用此库的项目冲突。

用法

异步请求

异步请求对于将缓慢的一次性任务(如发送电子邮件)推送到后台处理非常有用。一旦请求被发送,它将立即在后台进行处理。

扩展WP_Async_Request

class WP_Example_Request extends WP_Async_Request {

	/**
	 * @var string
	 */
	protected $prefix = 'my_plugin';

	/**
	 * @var string
	 */
	protected $action = 'example_request';

	/**
	 * Handle a dispatched request.
	 *
	 * Override this method to perform any actions required
	 * during the async request.
	 */
	protected function handle() {
		// Actions to perform.
	}

}

protected $prefix

应设置为与您的插件、主题或网站自定义函数前缀关联的唯一前缀。

protected $action

应设置为唯一名称。

protected function handle()

应在非阻塞请求期间执行任何逻辑。传递给请求的数据将通过$_POST访问。

发送请求

实例化请求

$this->example_request = new WP_Example_Request();

如有需要,向请求中添加数据

$this->example_request->data( array( 'value1' => $value1, 'value2' => $value2 ) );

发送请求

$this->example_request->dispatch();

支持链式调用

$this->example_request->data( array( 'data' => $data ) )->dispatch();

后台处理

后台处理与异步请求类似,但允许您排队任务。一旦队列保存并发送,队列中的项目将在后台进行处理。队列也将根据可用服务器资源进行扩展,因此高端服务器将每批处理更多项目。一旦一批完成,下一批将立即开始。

默认情况下,每5分钟运行一次健康检查,以确保存在排队项目时队列正在运行。如果队列失败,它将被重新启动。

队列基于先进先出原则运行,允许即使它已经在处理时,也可以将更多项目推送到队列。在另一个后台处理实例已经运行时保存新一批排队项目并发送,将导致发送快捷操作跳过,现有实例最终会抓取新项目并在轮到它时处理。

扩展WP_Background_Process

class WP_Example_Process extends WP_Background_Process {

	/**
	 * @var string
	 */
	protected $prefix = 'my_plugin';

	/**
	 * @var string
	 */
	protected $action = 'example_process';

	/**
	 * Perform task with queued item.
	 *
	 * Override this method to perform any actions required on each
	 * queue item. Return the modified item for further processing
	 * in the next pass through. Or, return false to remove the
	 * item from the queue.
	 *
	 * @param mixed $item Queue item to iterate over.
	 *
	 * @return mixed
	 */
	protected function task( $item ) {
		// Actions to perform.

		return false;
	}

	/**
	 * Complete processing.
	 *
	 * Override if applicable, but ensure that the below actions are
	 * performed, or, call parent::complete().
	 */
	protected function complete() {
		parent::complete();

		// Show notice to user or perform some other arbitrary task...
	}

}

protected $prefix

应设置为与您的插件、主题或网站自定义函数前缀关联的唯一前缀。

protected $action

应设置为唯一名称。

protected function task( $item )

应在队列中执行任何逻辑。返回false以从队列中删除项目,或返回$item以将其推回队列以进行进一步处理。如果项目已修改并推回队列,则将在退出批处理之前保存当前状态。

protected function complete()

可选地包含一旦队列完成时要执行的任何逻辑。

发送处理

实例化处理

$this->example_process = new WP_Example_Process();

注意:您必须无条件地实例化您的进程。所有请求都应该这样做,即使没有将任何内容推送到队列中。

将项目推送到队列

foreach ( $items as $item ) {
    $this->example_process->push_to_queue( $item );
}

项目可以是任何有效的PHP值,字符串、整数、数组或对象。如果需要,$item 在写入数据库时会进行序列化。

保存和分发队列

$this->example_process->save()->dispatch();

处理队列项目中的序列化对象

包含非标量值的队列项目在存储到数据库时会进行序列化。为了避免在unserialize过程中出现潜在的安全问题,此库提供了在调用unserialize()时设置allowed_classes选项的功能,这限制了可以实例化的类。它作为受保护的$allowed_batch_data_classes属性内部维护。

为了保持向后兼容性,默认值是true,这意味着任何序列化的对象都将被实例化。请注意,此默认行为可能在未来的主要版本中更改。

我们鼓励所有此库的用户利用设置$allowed_batch_data_classes的严格值。如果可能,将值设置为false以禁止实例化任何对象,或者非常有限的类名列表,请参见下面的示例。

不允许实例化的序列化字符串中的对象将获得类类型__PHP_Incomplete_Class

覆盖默认的$allowed_batch_data_classes

可以通过传递允许的类数组到构造函数来覆盖默认行为

$allowed_batch_data_classes = array( MyCustomItem::class, MyItemHelper::class );
$this->example_process = new WP_Example_Process( $allowed_batch_data_classes );

或者,将值设置为false

$this->example_process = new WP_Example_Process( false );

另一种更改默认值的方法是在您的进程类中覆盖$allowed_batch_data_classes属性

class WP_Example_Process extends WP_Background_Process {

	/**
	 * @var string
	 */
	protected $prefix = 'my_plugin';

	/**
	 * @var string
	 */
	protected $action = 'example_process';

	/**
	 *
	 * @var bool|array
	 */
	protected $allowed_batch_data_classes = array( MyCustomItem::class, MyItemHelper::class );
	...

后台进程状态

后台进程可以是排队、处理、暂停、取消或以上都不是(未启动或已完成)。

排队

要检查后台进程是否有排队项目,请使用is_queued()

if ( $this->example_process->is_queued() ) {
    // Do something because background process has queued items, e.g. add notice in admin UI.
}
处理中

要检查后台进程是否正在处理队列项目,请使用is_processing()

if ( $this->example_process->is_processing() ) {
    // Do something because background process is running, e.g. add notice in admin UI.
}
暂停

您可以使用pause()暂停后台进程。

$this->example_process->pause();

当前正在处理的数据包将继续,直到它完成或达到时间或内存限制。到那时,它将解锁进程,如果队列已空,则完成数据包,或者执行分发,这将导致处理程序删除健康检查cron并触发“暂停”操作。

要检查后台进程是否当前已暂停,请使用is_paused()

if ( $this->example_process->is_paused() ) {
    // Do something because background process is paused, e.g. add notice in admin UI.
}

您可以通过处理后台进程标识符($prefix + $action)的“暂停”操作来响应后台处理被暂停。

add_action( 'my_plugin_example_process_paused', function() {
    // Do something because background process is paused, e.g. add notice in admin UI.
});

您可以使用resume()恢复后台进程。

$this->example_process->resume();

您可以通过处理后台进程标识符($prefix + $action)的“恢复”操作来响应后台处理被恢复。

add_action( 'my_plugin_example_process_resumed', function() {
    // Do something because background process is resumed, e.g. add notice in admin UI.
});
已取消

您可以使用cancel()取消后台进程。

$this->example_process->cancel();

当前正在处理的数据包将继续,直到它完成或达到时间或内存限制。到那时,它将解锁进程,如果队列已空,则完成数据包,或者执行分发,这将导致处理程序删除健康检查cron,删除所有排队项目的所有数据包,并触发“取消”操作。

要检查后台进程是否当前已取消,请使用is_cancelled()

if ( $this->example_process->is_cancelled() ) {
    // Do something because background process is cancelled, e.g. add notice in admin UI.
}

您可以通过处理后台进程标识符($prefix + $action)的“取消”操作来响应后台处理被取消。

add_action( 'my_plugin_example_process_cancelled', function() {
    // Do something because background process is paused, e.g. add notice in admin UI.
});

“已取消”操作在队列被清理并取消状态删除后触发。之后,由于后台进程现在是休眠的,is_cancelled()将不再为真。

活跃

要检查后台进程是否有排队项目,是否正在处理,是否已暂停或正在取消,请使用is_active()

if ( $this->example_process->is_active() ) {
    // Do something because background process is active, e.g. add notice in admin UI.
}

如果后台进程不活跃,那么它要么还没有任何排队待处理的项目并且尚未启动,要么已经处理完所有排队项目。

BasicAuth

如果你的站点位于BasicAuth之后,异步请求和后台进程将无法完成。这是因为WP后台处理依赖于WordPress HTTP API,该API要求你将BasicAuth凭据附加到请求中。最简单的方法是使用以下过滤器

function wpbp_http_request_args( $r, $url ) {
	$r['headers']['Authorization'] = 'Basic ' . base64_encode( USERNAME . ':' . PASSWORD );

	return $r;
}
add_filter( 'http_request_args', 'wpbp_http_request_args', 10, 2);

贡献

我们欢迎通过拉取请求进行贡献,但请在开始工作之前请提出一个问题,以便讨论变更,如果没有已经存在的问题。如果你有一个已经批准的问题想要解决,请在该问题上发表评论,让其他人知道你将尝试解决它,以避免重复劳动造成的浪费。

单元测试与风格测试

在处理库时,请将单元测试添加到tests目录中适当的文件,以涵盖你的更改。

设置

我们使用标准的WordPress测试库来运行单元测试。

请运行以下命令来设置库

bin/install-wp-tests.sh db_name db_user db_pass

请根据需要替换db_namedb_userdb_pass

请注意,运行单元测试是一种破坏性操作数据库表将被清空,因此请使用专门用于运行单元测试的数据库名称。WordPress社区通常使用的标准数据库名称是wordpress_test,例如。

bin/install-wp-tests.sh wordpress_test root root

如果你遇到任何问题,请参阅WordPress手册的插件集成测试部分中的本地初始化测试环境部分。

运行单元测试

要运行单元测试,只需运行

make test-unit

如果composer依赖项尚未就绪,它们将自动安装。

运行风格测试

库中的代码使用一致的风格非常重要,这有助于快速理解它,并避免一些常见问题。《PHP_Code_Sniffer》与大部分标准WordPress规则一起使用,以帮助检查一致性。

要运行风格测试,只需运行

make test-style

如果composer依赖项尚未就绪,它们将自动安装。

运行所有测试

为了使事情尽可能简单,只需运行以下命令来运行所有测试

make

如果composer依赖项尚未就绪,它们将自动安装。

创建PR

在创建PR时,请确保在描述的顶部提及要解决的哪个GitHub问题,例如。

解决#123

单元测试和风格测试将自动运行,除非通过,否则PR将无法合并,并且分支必须与master保持最新。

许可

GPLv2+