dimitri/libphp-pgq

此包的最新版本(v2.0-alpha)没有可用的许可证信息。

PGQ PostgreSQL 队列解决方案的 PHP 级别 API

v2.0-alpha 2018-02-09 10:33 UTC

This package is not auto-updated.

Last update: 2024-09-15 04:52:33 UTC


README

简介

此项目提供 PHP 级别 API 以使用 PGQ SQL API。

关于 PGQ 的更多信息请参阅此处: http://skytools.projects.postgresql.org/doc/pgq-sql.html http://www.pgcon.org/2008/schedule/events/79.en.html

然后它提供了一些你想要扩展的消费者类型。所有消费者都需要你实现自己的 process_event(&$event) 回调函数,并会关注 PGQ 的内部功能。

PGQ 有关在(工作)队列中生成事件并让一个或多个消费者获取这些事件,批量处理并处理它们。这里要展示的 PHP 类所做的是获取批次并调用你自己的 process_event() 函数来处理每个事件。

它可在 packagist.org 上找到。

工具

SimpleLogger

此类处理带有 loglevel 的日志记录:只有比当前 loglevel 重要的消息才会写入日志文件。级别按重要性递增

  • DEBUG

  • VERBOSE

  • NOTICE

  • WARNING

  • ERROR

  • FATAL

SimpleLogger 为每个 loglevel 提供了一个方法,该方法接受一个格式字符串然后是参数,就像 sprintf() 一样。例如,你有

$logger->debug("a message with a '%s' string", $str);

SystemDaemon

此类实现了一个可以通过命令控制的 System Daemon。原理是在后台运行并无限循环,尽可能在两个循环之间进行 $this->delay 休息。

SystemDaemon 使用 SimpleLogger 的 $this->log 实例,并在重新加载时重新打开其日志文件。这意味着它与 logrotate 兼容,但不要忘记在 logrotate 后处理时间重新加载守护进程。

任何 SystemDaemon 可用的命令有:start、stop、kill、reload、restart、status、logless、logmore。

stop 和 kill 之间的区别在于,在前一种情况下,守护进程将终止当前处理,并在下一个有机会休息 $this->delay 之前停止,而 kill 则强制它退出(调用 $this->stop())。

reload 命令将在下一次睡眠机会时让守护进程调用用户定义的 $this->reload() 命令。此命令可以例如读取配置文件并更改设置。

logless 和 logmore 命令被认为是无延迟的,可以使使用的记录器立即更详细或更简洁,通过增加或减少其 loglevel。这在你想确切知道守护进程现在正在做什么,但无法承担重新启动它的时候很有用。

实现 SystemDaemon 时,你需要实现 $this->config() 和 $this->process() 函数,这两个函数将在无限循环中被调用。前者只有在重新加载已下令(SIGHUP)时才会被调用,而后者在每次循环中都会被调用。

SystemDaemon 还会将其 SimpleLogger 实例注册为 PHP 错误处理程序,并在遇到 PHP FATAL 错误(之一 E_STRICT、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING)时考虑退出,并将用户定义的 $this->php_error_hook() 调用用于 PHP E_ERROR 或 E_USER_ERROR 级别的错误。

PGQ

这是一个抽象类,为 PGQ SQL API 提供的每个 SQL 函数都有一个公共静态方法。如果 PHP 了解命名空间或模块,这将是一个模块。

消费者

这些类负责处理PGQ的实际工作方式。它们将从队列中获取批次,从批次中获取事件,允许您通过调用用户定义的 $this->process_event(&$event) 函数来处理事件,并在适当的时候调用 finish_batch()。

$this->process_event() 函数应返回以下返回代码之一

PGQ_EVENT_OK

当事件处理令人满意时。

PGQ_EVENT_FAILED

事件被标记为失败,原因如下 $event->failed_reason,并且在使用 PGQEventRemoteConsumer 时,相关远程数据库上的处理将被回滚。

PGQ_EVENT_RETRY

事件被标记为重试,并在 $event->retry_delay 秒的最小延迟后重新插入主队列。在使用 PGQEventRemoteConsumer 时,相关远程数据库上的处理将被回滚。

PGQ_ABORT_BATCH

取消所有当前的批次处理,在远程和队列数据库上(当使用某种形式的 RemoteConsumer 时)。批次未完成,因此在下一次运行时您将再次收到事件。

PGQConsumer

这是一个 SystemDaemon,它实现了更多命令,以便安装队列并注册消费者。

当扩展 PGQConsumer 时,您需要实现 $this->config() 和 $this->process_event() 函数,然后您就完成了。

构造函数需要一个队列名称(qname)、一个消费者名称(cname)和一个数据库连接字符串。

增加的命令包括

install

创建队列 qname 并注册消费者 cname。

uninstall

注销消费者 cname 并删除队列 qname。

check

仅当队列 qname 存在且消费者 cname 已注册时为真。

create_queue

创建队列 qname。

drop_queue

删除队列 qname。

register

注册消费者 cname。

unregister

注销消费者 cname。

failed

打印出队列 qname 和消费者 cname 的失败事件列表。

delete

删除给定的事件 ID,或如果给定 all 作为事件 ID,则删除所有失败事件。

retry

重试给定的事件 ID,或如果给定 all 作为事件 ID,则重试所有失败事件。

PGQInteractiveConsumer

此类假设循环将在其他地方完成,例如在调用站点。它将消耗所有可用的事件(直到 next_batch() 返回 null 为止)。

延迟不由实现类控制,而由其使用者控制。

实现者必须调用 $this->process(),这将开始消耗所有可用的事件,并为每个事件调用 $this->process_event(&$event) 钩子。

内部设计说明

由于 PHP 从一个基类扩展的限制,PGQInteractiveRemoteConsumer 需要自己实现所有 PGQ 方法:PGQConsumer 无法同时扩展 SystemDaemon 和 PGQClass,其中我们应该将类抽象放在 API 模块之上。

PGQRemoteConsumer

PGQRemoteConsumer 是一个 PGQConsumer,控制两个 PostgreSQL 连接,并将妥善处理两个连接上的 COMMIT 和 ROLLBACK。

这意味着您想使用 PGQRemoteConsumer 从一个数据库处理事件并将更改应用到另一个数据库(远程数据库)。PGQRemoteConsumer 利用远程处理是事务性的(在数据库上发生)这一事实,以确保任何 COMMIT 的工作都与正确消费的事件相关联。

事件消费或远程处理中的任何错误都会导致当前批次处理在两个位置回滚,这意味着事件将在以后再次消费。

PGQEventRemoteConsumer

当您需要能够在事件级别同时 COMMIT 或 ROLLBACK 两个事务时,PGQEventRemoteConsumer 就是您想要的。它将为每个事件使用子事务(SAVEPOINT),并将能够在远程端对单个事件处理相关的任何处理错误回滚到 SAVEPOINT。

PGQCoopConsumer

该消费者将在所有子消费者进程之间共享批次。您需要单独注册每个子消费者。