Skip to content

Conversation

@huangdijia
Copy link
Contributor

@huangdijia huangdijia commented Nov 15, 2025

Summary

This PR consolidates the async queue closure functionality into the support package, eliminating circular dependencies and simplifying the package structure.

Key Changes

  • Moved core classes: CallQueuedClosure and ClosureParameterInjection trait from async-queue-closure-job to support package
  • Updated dependencies: Made async-queue-closure-job depend on support package instead of duplicating functionality
  • Cleaned up dependencies: Removed unnecessary dependencies from async-queue-closure-job composer.json
  • Enhanced AMQP dispatch: Added setExchange() and setRoutingKey() methods to PendingAmqpProducerMessageDispatch for better fluent API support
  • Improved encapsulation: Changed property visibility from public to protected in dispatch classes
  • Removed duplicate tests: Removed tests from async-queue-closure-job package (functionality now tested in support package)

Benefits

  1. Eliminates circular dependency: The support package previously depended on async-queue-closure-job, which created a circular dependency
  2. Single source of truth: Core closure job functionality now lives in one place
  3. Simplified dependency tree: Reduces the number of packages that need to be maintained
  4. Better API: Enhanced fluent API for AMQP message dispatch with exchange and routing key setters
  5. Better encapsulation: Protected properties prevent accidental external modification

Migration Path

For users of async-queue-closure-job, this is a non-breaking change as the package now re-exports the functionality from support. The namespace and API remain the same.

Test Plan

  • All existing functionality preserved through namespace re-exports
  • Enhanced AMQP dispatch methods available
  • No breaking changes to public API

Summary by CodeRabbit

发布说明

  • 新功能

    • AMQP 消息派发新增 setExchange() 和 setRoutingKey() 方法,用于配置消息路由。
    • dispatch 调度入口已委托到统一支持库的实现(含弃用提示)。
  • 重构

    • 调整若干类的命名空间与继承关系,改进封装与可维护性。
    • 将部分消息派发类属性由 public 调整为 protected。
  • 杂项

    • 精简/调整依赖声明,合并支持库相关依赖。
  • 文档

    • 完整更新了包的使用说明与迁移指南。
  • 测试

    • 移除若干已过时的单元测试文件。

This refactoring consolidates the async queue closure functionality into the support package, eliminating circular dependencies and simplifying the package structure.

Changes:
- Move CallQueuedClosure and ClosureParameterInjection from async-queue-closure-job to support package
- Update async-queue-closure-job to depend on support package instead
- Remove duplicate dependencies from async-queue-closure-job
- Add laravel/serializable-closure dependency to support package
- Update all references to use the new location
- Remove tests from async-queue-closure-job (tests will be maintained in support package)
- Add setExchange() and setRoutingKey() methods to PendingAmqpProducerMessageDispatch
- Change property visibility from public to protected in dispatch classes for better encapsulation
@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

Walkthrough

将 CallQueuedClosure 与相关 traits 从 AsyncQueueClosureJob 命名空间迁移到 Support 命名空间;async-queue-closure-job 包依赖简化并将 dispatch 委托到通用 dispatch;调整 AMQP/Kafka Pending dispatch 类的属性可见性并新增 AMQP 路由/交换机 setter;删除多份 AsyncQueueClosureJob 相关测试与类型断言。

Changes

Cohort / File(s) 变更摘要
命名空间迁移
src/support/src/CallQueuedClosure.php, src/support/src/Traits/ClosureParameterInjection.php
将命名空间从 FriendsOfHyperf\AsyncQueueClosureJob 改为 FriendsOfHyperf\Support(仅命名空间/路径变更)。
async-queue-closure-job 包调整
src/async-queue-closure-job/composer.json, src/async-queue-closure-job/src/ConfigProvider.php, src/async-queue-closure-job/src/Functions.php
composer.json 移除多项依赖并改为依赖/升级 hyperf/support;ConfigProvider 现在返回空数组;dispatch() 改为委托到基础 dispatch(别名 base_dispatch),并加入弃用说明。
支持包依赖与移除反向依赖
src/support/composer.json
从 support 包中移除对 friendsofhyperf/async-queue-closure-job 的 require,新增 laravel/serializable-closure 依赖约束 `^1.0
ClosureJob 继承更新
src/support/src/AsyncQueue/ClosureJob.php
基类从完全限定的 \FriendsOfHyperf\AsyncQueueClosureJob\CallQueuedClosure 改为本地导入的 CallQueuedClosure(配合命名空间迁移)。
Helpers / 导入修正
src/helpers/src/Functions.php, src/support/src/Functions.php
更新/替换 CallQueuedClosure 的导入为 FriendsOfHyperf\Support\CallQueuedClosure 或移除旧导入,相关函数改为引用迁移后的实现(需核查所有引用一致性)。
AMQP 消息分派增强
src/support/src/Bus/PendingAmqpProducerMessageDispatch.php
$pool$timeout$confirm 可见性从 public → protected;新增受保护属性 $routingKey$exchange;新增公有 setter setExchange(string): static 与 `setRoutingKey(array
Kafka 分派可见性调整
src/support/src/Bus/PendingKafkaProducerMessageDispatch.php
$pool 可见性从 public → protected(其余逻辑不变)。
函数/工具调整
src/support/src/CallQueuedClosure.php, src/support/src/Functions.php
CallQueuedClosure 类文件已移动并改命名空间;部分工具函数的 use/import 已相应调整或删除(建议验证无遗漏引用)。
Traits 命名空间
src/support/src/Traits/ClosureParameterInjection.php
Traits 文件命名空间从 FriendsOfHyperf\AsyncQueueClosureJob\TraitsFriendsOfHyperf\Support\Traits
测试与类型断言删除
tests/AsyncQueueClosureJob/*, types/AsyncQueueClosureJob/Functions.php
删除多个 AsyncQueueClosureJob 相关的 PHPUnit 测试文件与类型断言文件(完整移除测试套件)。
文档更新
src/async-queue-closure-job/README.md, src/support/README.md
README 重写,说明核心实现迁移到 support 包、使用示例与架构说明,测试节替换为包结构/迁移指南等文档性更新。

Sequence Diagram(s)

sequenceDiagram
    participant App as 应用代码
    participant SupportDispatch as FriendsOfHyperf\Support::dispatch
    participant Call as CallQueuedClosure (Support)
    participant Queue as 队列/消息系统

    Note over App,SupportDispatch: dispatch 委托路径(统一入口)
    App->>SupportDispatch: dispatch(closure)
    alt 需要包装闭包
        SupportDispatch->>Call: CallQueuedClosure::create(closure)
        Call-->>SupportDispatch: PendingJob 实例
    end
    SupportDispatch->>Queue: 将任务序列化并发送
    alt AMQP 且 routing/exchange 设置
        SupportDispatch->>Queue: 设置 routingKey / exchange(由 PendingAmqpProducerMessageDispatch 提供)
    end
Loading

Estimated code review effort

🎯 3 (中等) | ⏱️ ~25 分钟

需要额外关注:

  • src/support/src/Bus/PendingAmqpProducerMessageDispatch.php:可见性变化、新 setter 与析构写入底层消息的耦合点。
  • 导入/引用完整性:核查所有对 CallQueuedClosure 的引用是否指向新的 FriendsOfHyperf\Support 命名空间,尤其是 src/support/src/Functions.php 与 helpers。
  • 测试删除:确认被删除的测试覆盖的行为是否已在其他仓库/包中保留或计划迁移。

Possibly related PRs

Suggested reviewers

  • xuanyanwow
  • zds-s

Poem

🐰 我把闭包轻轻抱进新巢,
名字换了门牌不改跳跃,
调度走中枢,路由学会藏,
测试去旅行,文档唱新调。 ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了拉取请求的核心变化——将 CallQueuedClosure 整合到 support 包中,这是本次重构的主要目标。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/consolidate-closure-job-to-support

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.1.31)

At least one path must be specified to analyse.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/support/src/Bus/PendingAmqpProducerMessageDispatch.php (1)

40-48: 使用布尔短路会忽略空字符串/空数组的 routingKey/exchange

这里用 $this->routingKey && ... / $this->exchange && ... 做布尔短路,会导致以下情况被静默忽略:

  • setRoutingKey('')setRoutingKey([]) 时,析构函数不会调用 setRoutingKey()
  • setExchange('') 时,也不会调用 setExchange()

如果调用方希望显式将消息的 exchange/routingKey 置为空值或空数组,这个实现会违背调用方预期。建议只以 null 作为「未设置」的判定条件,例如:

-        $this->routingKey && $this->message->setRoutingKey($this->routingKey);
-        $this->exchange && $this->message->setExchange($this->exchange);
+        if ($this->routingKey !== null) {
+            $this->message->setRoutingKey($this->routingKey);
+        }
+        if ($this->exchange !== null) {
+            $this->message->setExchange($this->exchange);
+        }

这样即便传入空字符串或空数组,也会被如实下发到底层消息对象。

🧹 Nitpick comments (2)
src/async-queue-closure-job/src/Functions.php (1)

16-16: 未使用的导入。

第 16 行导入了 CallQueuedClosure,但在函数实现中未使用(第 28 行直接委托给 base_dispatch)。可以移除此导入以保持代码整洁。

应用此差异移除未使用的导入:

-use FriendsOfHyperf\Support\CallQueuedClosure;
-
 use function FriendsOfHyperf\Support\dispatch as base_dispatch;
src/support/src/Bus/PendingAmqpProducerMessageDispatch.php (1)

71-81: 新 setExchange/setRoutingKey API 设计合理,可考虑补充文档

两个新 setter 使用 static 返回值实现链式调用,参数类型与属性类型保持一致,与类中已有的 setPayload/setConfirm/setTimeout 风格统一,看起来没有问题。

可以考虑在类级注释或方法 phpdoc 中简单说明一下 setRoutingKey(array|string $routingKey) 的用法(何时传 string,何时传 array),方便 IDE 提示和使用者理解,但这只是文档层面的优化。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 021883e and 78eb948.

📒 Files selected for processing (15)
  • src/async-queue-closure-job/composer.json (0 hunks)
  • src/async-queue-closure-job/src/ConfigProvider.php (1 hunks)
  • src/async-queue-closure-job/src/Functions.php (2 hunks)
  • src/helpers/src/Functions.php (1 hunks)
  • src/support/composer.json (1 hunks)
  • src/support/src/AsyncQueue/ClosureJob.php (1 hunks)
  • src/support/src/Bus/PendingAmqpProducerMessageDispatch.php (3 hunks)
  • src/support/src/Bus/PendingKafkaProducerMessageDispatch.php (1 hunks)
  • src/support/src/CallQueuedClosure.php (1 hunks)
  • src/support/src/Functions.php (0 hunks)
  • src/support/src/Traits/ClosureParameterInjection.php (1 hunks)
  • tests/AsyncQueueClosureJob/BasicFunctionalityTest.php (0 hunks)
  • tests/AsyncQueueClosureJob/CallQueuedClosureCreateTest.php (0 hunks)
  • tests/AsyncQueueClosureJob/ClosureJobTest.php (0 hunks)
  • types/AsyncQueueClosureJob/Functions.php (0 hunks)
💤 Files with no reviewable changes (6)
  • src/support/src/Functions.php
  • src/async-queue-closure-job/composer.json
  • tests/AsyncQueueClosureJob/ClosureJobTest.php
  • tests/AsyncQueueClosureJob/CallQueuedClosureCreateTest.php
  • tests/AsyncQueueClosureJob/BasicFunctionalityTest.php
  • types/AsyncQueueClosureJob/Functions.php
🧰 Additional context used
🧬 Code graph analysis (3)
src/helpers/src/Functions.php (1)
src/support/src/CallQueuedClosure.php (1)
  • CallQueuedClosure (21-55)
src/async-queue-closure-job/src/Functions.php (2)
src/support/src/CallQueuedClosure.php (1)
  • CallQueuedClosure (21-55)
src/support/src/Functions.php (1)
  • dispatch (33-45)
src/support/src/AsyncQueue/ClosureJob.php (1)
src/support/src/CallQueuedClosure.php (1)
  • CallQueuedClosure (21-55)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
🔇 Additional comments (8)
src/support/src/CallQueuedClosure.php (1)

12-12: 命名空间迁移正确。

命名空间从 FriendsOfHyperf\AsyncQueueClosureJob 迁移到 FriendsOfHyperf\Support 符合 PR 目标,消除循环依赖并将核心功能整合到 support 包中。

src/support/src/Traits/ClosureParameterInjection.php (1)

12-12: 命名空间迁移正确。

Trait 的命名空间从 FriendsOfHyperf\AsyncQueueClosureJob\Traits 迁移到 FriendsOfHyperf\Support\Traits,与 CallQueuedClosure 的迁移保持一致。

src/support/src/Bus/PendingKafkaProducerMessageDispatch.php (1)

29-29: 改进了封装性。

$pool 属性的可见性从 public 改为 protected 是良好的封装实践。由于 onPool() 方法(第 43 行)提供了 fluent 设置器,因此不会破坏公共 API。

src/helpers/src/Functions.php (1)

22-22: 导入更新正确。

CallQueuedClosure 的导入已正确更新为新的命名空间 FriendsOfHyperf\Support\CallQueuedClosure。第 200 行的 CallQueuedClosure::create($job) 用法保持不变,确保了向后兼容性。由于此函数已被弃用(第 193 行),这一更改不会影响现有功能。

src/support/composer.json (1)

31-31: laravel/serializable-closure 依赖项版本兼容。

添加 laravel/serializable-closure 依赖是必要的,因为 CallQueuedClosure 类使用 SerializableClosure。版本约束 ^1.0 || ^2.0 已验证与最新版本 v2.0.6 兼容,该版本需要 PHP ^8.1。

src/async-queue-closure-job/src/ConfigProvider.php (1)

16-19: 原始审查评论的关切已消除,无破坏性变化。

验证结果表明 ConfigProvider 返回空数组是正确的:

  • 之前的配置中 'dependencies' 本就为空数组,未注册任何服务
  • 注解扫描路径已移除,因为 async-queue-closure-job 包中不存在任何需要扫描的 Hyperf 属性注解(#[...])
  • 核心功能 CallQueuedClosure 已正确移至 support 包
  • 该包现在通过 Functions.php 中的 dispatch() 辅助函数重新导出 support 包的功能
  • 重构完整且干净,无破坏性变更
src/async-queue-closure-job/src/Functions.php (1)

26-29: 验证返回类型兼容性:正确

根据验证,函数的返回类型声明与实际返回值完全兼容:

  1. CallQueuedClosure 继承自 Hyperf\AsyncQueue\Job
  2. Hyperf\AsyncQueue\Job 实现 JobInterface 接口
  3. base_dispatch 接收 Closure 时,将其转换为 CallQueuedClosure 实例(第 36 行)
  4. 匹配表达式第 42 行条件满足:$job instanceof JobInterface 返回 true
  5. 返回 PendingAsyncQueueDispatch 实例

函数声明的返回类型 PendingAsyncQueueDispatch 与实际返回值完全一致,无兼容性问题。

src/support/src/Bus/PendingAmqpProducerMessageDispatch.php (1)

26-34: 属性改为 protected 的兼容性注意

这些属性之前是 public(从 PR 描述可知),现在改为 protected,外部如果直接访问 $pool/$timeout/$confirm/$routingKey/$exchange 会直接报「Cannot access protected property」。虽然已有 onPool()/setTimeout()/setConfirm()/setExchange()/setRoutingKey() 这些封装方法,这个改动在封装性上是进步,但在语义上仍然属于 BC 变更,建议确认该类是否只被视为内部对象,或者在变更说明中明确这一点。

@huangdijia huangdijia merged commit aae5790 into main Nov 15, 2025
21 of 22 checks passed
@huangdijia huangdijia deleted the refactor/consolidate-closure-job-to-support branch November 15, 2025 01:02
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f46cade and 47c709e.

📒 Files selected for processing (4)
  • src/async-queue-closure-job/README.md (2 hunks)
  • src/async-queue-closure-job/src/Functions.php (1 hunks)
  • src/support/README.md (1 hunks)
  • tests/Support/DispatchTest.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/async-queue-closure-job/src/Functions.php (3)
src/support/src/CallQueuedClosure.php (1)
  • CallQueuedClosure (21-55)
src/support/src/Functions.php (1)
  • dispatch (33-45)
src/support/src/Bus/PendingAsyncQueueDispatch.php (1)
  • PendingAsyncQueueDispatch (19-56)
tests/Support/DispatchTest.php (1)
src/support/src/CallQueuedClosure.php (1)
  • CallQueuedClosure (21-55)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
🔇 Additional comments (7)
src/async-queue-closure-job/README.md (2)

9-9: 版本说明清晰准确

第9行新增的版本说明恰当地传达了重构信息,明确指出从v3.1.73开始的架构变更。文案简洁且说明了核心目的。


114-145: "Package Architecture"部分结构良好且信息完整

新增的架构说明部分表现出色:

  • 第119-120行准确列举了迁移至support包的核心类和trait
  • 第126-129行清晰阐述了重构的四个关键原因,与PR目标相符
  • 第133行强调"无需操作"维护了向后兼容性承诺
  • 第135-141行的代码示例对比清晰,帮助用户理解新旧用法
  • 第145行简明扼要地说明测试迁移情况

文档准确反映了架构变更且能有效引导用户,保持了API的可用性和易迁移性。

tests/Support/DispatchTest.php (2)

18-18: LGTM!命名空间迁移正确。

FriendsOfHyperf\Support 导入 CallQueuedClosure 与本次重构的目标一致,功能已迁移到 support 包以消除循环依赖。


55-68: LGTM!测试正确验证了新命名空间的行为。

测试正确验证了 dispatch() 函数在使用闭包时会创建来自 FriendsOfHyperf\Support 命名空间的 CallQueuedClosure 实例,与重构目标一致。

src/async-queue-closure-job/src/Functions.php (3)

16-18: 导入语句正确支持重构。

新增的导入语句符合将功能整合到 support 包的目标:

  • CallQueuedClosure:虽然在函数体中未直接使用,但第 26 行的 @param-closure-this 注解引用了它,这对 IDE 和静态分析工具的类型解析很重要
  • base_dispatch:作为第 30 行的委托目标函数

这些导入正确地支持了从本地实现到 support 包的迁移。


23-24: 弃用通知清晰明确。

弃用说明提供了完整的版本信息(自 3.1.73 起弃用,将在 3.2 移除),并明确指引用户迁移到 FriendsOfHyperf\Support\dispatch。这种渐进式迁移方式符合向后兼容的最佳实践。


28-31: 实现委托正确,行为已验证一致。

通过代码库搜索确认,该函数的委托实现完全正确:

  • base_dispatch 是从 src/support/src/Functions.php 导入的 dispatch 函数,它将 Closure 包装成 CallQueuedClosure 实例(extends Job implements JobInterface
  • base_dispatch 随后为 JobInterface 实例返回 PendingAsyncQueueDispatch
  • tests/Support/DispatchTest.php 明确验证了此行为:闭包分发返回 PendingAsyncQueueDispatch,底层工作对象为 CallQueuedClosure
  • 闭包的 $this 绑定通过 @param-closure-this CallQueuedClosure 注解保证被绑定到 CallQueuedClosure 实例
  • 方法链式调用正常工作,因为 PendingAsyncQueueDispatch 提供流畅接口

所有行为完全一致,无需修改。

Comment on lines +29 to +53
#### Async Queue (Closure Jobs)

```php
use function FriendsOfHyperf\Support\dispatch;

// Simple closure dispatch to async queue
dispatch(function () {
// Your job logic here
logger()->info('Job executed!');
});

// With configuration
dispatch(function () {
// Your job logic here
})
->onConnection('high-priority')
->delay(60) // Execute after 60 seconds
->setMaxAttempts(5);

// With dependency injection
dispatch(function (UserService $userService, LoggerInterface $logger) {
$users = $userService->getActiveUsers();
$logger->info('Processing ' . count($users) . ' users');
});
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

文档与实现不一致:方法名错误。

示例代码中使用了 onConnection() 方法(第 44 行),但根据测试文件 tests/Support/DispatchTest.php 的实际实现,PendingAsyncQueueDispatch 使用的是 onPool() 方法,而非 onConnection()

测试文件中的证据:

  • 第 113 行:$pending->onPool('custom-pool')
  • 第 154 行:->onPool('high-priority')
  • 第 192 行:->onPool('test-pool')

应用此修改以纠正方法名:

 dispatch(function () {
     // Your job logic here
 })
-    ->onConnection('high-priority')
+    ->onPool('high-priority')
     ->delay(60) // Execute after 60 seconds
     ->setMaxAttempts(5);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#### Async Queue (Closure Jobs)
```php
use function FriendsOfHyperf\Support\dispatch;
// Simple closure dispatch to async queue
dispatch(function () {
// Your job logic here
logger()->info('Job executed!');
});
// With configuration
dispatch(function () {
// Your job logic here
})
->onConnection('high-priority')
->delay(60) // Execute after 60 seconds
->setMaxAttempts(5);
// With dependency injection
dispatch(function (UserService $userService, LoggerInterface $logger) {
$users = $userService->getActiveUsers();
$logger->info('Processing ' . count($users) . ' users');
});
```
#### Async Queue (Closure Jobs)
🤖 Prompt for AI Agents
In src/support/README.md around lines 29 to 53, the documentation uses the wrong
method name: it calls onConnection() at line 44 while the implementation/tests
expect onPool(). Update the README examples to use ->onPool('...') wherever
onConnection() appears (including the high-priority example) so the docs match
PendingAsyncQueueDispatch's API and the tests.

Comment on lines +102 to +120
#### PendingAsyncQueueDispatch

Fluent API for async queue job dispatch:

```php
use FriendsOfHyperf\Support\Bus\PendingAsyncQueueDispatch;

$pending = new PendingAsyncQueueDispatch($job);
$pending
->onConnection('default')
->delay(30)
->when($condition, function ($dispatch) {
$dispatch->onConnection('special');
})
->unless($otherCondition, function ($dispatch) {
$dispatch->delay(60);
});
// Job is dispatched when object is destroyed
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

文档与实现不一致:方法名错误。

示例中使用了 onConnection() 方法(第 111、114 行),但实际实现使用的是 onPool() 方法。

应用此修改以纠正方法名:

 $pending = new PendingAsyncQueueDispatch($job);
 $pending
-    ->onConnection('default')
+    ->onPool('default')
     ->delay(30)
     ->when($condition, function ($dispatch) {
-        $dispatch->onConnection('special');
+        $dispatch->onPool('special');
     })
     ->unless($otherCondition, function ($dispatch) {
         $dispatch->delay(60);
     });
🤖 Prompt for AI Agents
In src/support/README.md around lines 102 to 120 the example uses the
non-existent method onConnection (lines ~111 and ~114) while the implementation
exposes onPool; update the documentation example to call onPool instead of
onConnection (replace both occurrences) so the README matches the actual API,
and verify any surrounding text references the connection naming to reflect
"pool" terminology.

Comment on lines +151 to +165
### Conditional Execution

All pending dispatch classes support conditional execution:

```php
use function FriendsOfHyperf\Support\dispatch;

dispatch($job)
->when($shouldUseHighPriority, function ($dispatch) {
$dispatch->onConnection('high-priority');
})
->unless($isTestMode, function ($dispatch) {
$dispatch->delay(10);
});
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

文档与实现不一致:方法名错误。

条件执行示例中使用了 onConnection() 方法(第 160 行),但应为 onPool()

应用此修改:

 dispatch($job)
     ->when($shouldUseHighPriority, function ($dispatch) {
-        $dispatch->onConnection('high-priority');
+        $dispatch->onPool('high-priority');
     })
     ->unless($isTestMode, function ($dispatch) {
         $dispatch->delay(10);
     });
🤖 Prompt for AI Agents
In src/support/README.md around lines 151 to 165, the conditional execution
example uses the wrong method name: it calls onConnection() (line ~160) but the
implementation expects onPool(); update the example to call onPool() instead and
ensure the surrounding text/example remains consistent with the library API.

Comment on lines +178 to +185
### PendingAsyncQueueDispatch Methods

- `onConnection(string $connection): static` - Set queue connection
- `delay(int $delay): static` - Delay job execution (seconds)
- `setMaxAttempts(int $attempts): static` - Set max retry attempts
- `when(mixed $condition, callable $callback): static` - Conditional execution
- `unless(mixed $condition, callable $callback): static` - Inverse conditional execution

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

API 文档错误:方法名不匹配。

第 180 行将方法文档化为 onConnection(string $connection),但根据测试文件的实际实现,该方法应为 onPool(string $pool)

应用此修改:

 ### PendingAsyncQueueDispatch Methods
 
-- `onConnection(string $connection): static` - Set queue connection
+- `onPool(string $pool): static` - Set queue pool
 - `delay(int $delay): static` - Delay job execution (seconds)
 - `setMaxAttempts(int $attempts): static` - Set max retry attempts
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### PendingAsyncQueueDispatch Methods
- `onConnection(string $connection): static` - Set queue connection
- `delay(int $delay): static` - Delay job execution (seconds)
- `setMaxAttempts(int $attempts): static` - Set max retry attempts
- `when(mixed $condition, callable $callback): static` - Conditional execution
- `unless(mixed $condition, callable $callback): static` - Inverse conditional execution
### PendingAsyncQueueDispatch Methods
- `onPool(string $pool): static` - Set queue pool
- `delay(int $delay): static` - Delay job execution (seconds)
- `setMaxAttempts(int $attempts): static` - Set max retry attempts
- `when(mixed $condition, callable $callback): static` - Conditional execution
- `unless(mixed $condition, callable $callback): static` - Inverse conditional execution
🤖 Prompt for AI Agents
In src/support/README.md around lines 178 to 185, the API docs incorrectly list
onConnection(string $connection): static; update the doc to match the
implementation and tests by renaming the method to onPool(string $pool): static
and adjust the parameter name and description accordingly (e.g., "Set queue
pool") so the README reflects the real method signature and behavior.

Comment on lines +186 to +195
### PendingAmqpProducerMessageDispatch Methods

- `setPool(string $pool): static` - Set AMQP pool name
- `setExchange(string $exchange): static` - Set exchange name
- `setRoutingKey(array|string $routingKey): static` - Set routing key(s)
- `setTimeout(int $timeout): static` - Set timeout (seconds)
- `setConfirm(bool $confirm): static` - Enable/disable confirm mode
- `when(mixed $condition, callable $callback): static` - Conditional execution
- `unless(mixed $condition, callable $callback): static` - Inverse conditional execution

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

验证 AMQP 方法的可用性。

文档记录了 setExchange()setRoutingKey() 方法(第 189-190 行),这些是 PR 中新增的增强功能。但是,第 188 行文档化为 setPool(),而测试文件显示实际使用的是 onPool() 方法(tests/Support/DispatchTest.php 第 227 行)。

请确认:

  1. setExchange()setRoutingKey() 方法确实已在 PendingAmqpProducerMessageDispatch 中实现
  2. 池配置方法应为 onPool() 还是 setPool()

运行以下脚本验证方法签名:


🏁 Script executed:

#!/bin/bash
# 描述:验证 PendingAmqpProducerMessageDispatch 类的方法签名

# 查找类定义及其所有公共方法
ast-grep --pattern $'class PendingAmqpProducerMessageDispatch {
  $$$
}'

# 搜索 setExchange 方法
rg -nP --type=php -C3 'function\s+setExchange\s*\('

# 搜索 setRoutingKey 方法  
rg -nP --type=php -C3 'function\s+setRoutingKey\s*\('

# 搜索 setPool 或 onPool 方法
rg -nP --type=php -C3 'function\s+(setPool|onPool)\s*\(' -g '*PendingAmqpProducerMessageDispatch.php'

Length of output: 8260


更新 README 文档中的池配置方法名称。

验证确认 setExchange()setRoutingKey() 方法已正确实现,但第 188 行的文档存在错误。实现中的方法名为 onPool()(位于 src/support/src/Bus/PendingAmqpProducerMessageDispatch.php 第 50 行),而不是 setPool()

需要修正:

  • 第 188 行:setPool(string $pool): staticonPool(string $pool): static
🤖 Prompt for AI Agents
In src/support/README.md around lines 186 to 195, the documented pool
configuration method name is incorrect: update line 188 to replace
"setPool(string $pool): static" with "onPool(string $pool): static"; also verify
the implementation signature in
src/support/src/Bus/PendingAmqpProducerMessageDispatch.php (around line 50)
matches onPool(string $pool): static and adjust the README only if the
implementation is correct.

huangdijia added a commit that referenced this pull request Nov 15, 2025
* refactor: consolidate CallQueuedClosure to support package

This refactoring consolidates the async queue closure functionality into the support package, eliminating circular dependencies and simplifying the package structure.

Changes:
- Move CallQueuedClosure and ClosureParameterInjection from async-queue-closure-job to support package
- Update async-queue-closure-job to depend on support package instead
- Remove duplicate dependencies from async-queue-closure-job
- Add laravel/serializable-closure dependency to support package
- Update all references to use the new location
- Remove tests from async-queue-closure-job (tests will be maintained in support package)
- Add setExchange() and setRoutingKey() methods to PendingAmqpProducerMessageDispatch
- Change property visibility from public to protected in dispatch classes for better encapsulation

* fix: update hyperf/support version to ~3.1.73 in composer.json

* refactor: update README and deprecate dispatch function in async-queue-closure-job package

---------

Co-Authored-By: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants