6

我尝试使用 Cro 创建一个将在 rabbitMQ 中发布消息的 Rest API。我想将我的路线分成不同的模块,并用“包含”组合它们。但我也希望能够在每个模块中共享与 rabbitMQ 的相同连接。我尝试使用“我们的”,但它不起作用:

文件 1:

unit module XXX::YYY;
use Cro::HTTP::Router;
use Cro::HTTP::Server;
use Cro::HTTP::Log::File;
use XXX::YYY::Route1;

use Net::AMQP;

our $rabbitConnection is export = Net::AMQP.new;
await $rabbitConnection.connect;

my $application = route {
        include <api v1 run> => run-routes;
}
...

文件 2:

unit module XXX::YYY::Route1;
use UUID;
use Cro::HTTP::Router;
use JSON::Fast;
use Net::AMQP;
my $channel = $XXX::YYY::rabbitConnection.open-channel().result;
$channel.declare-queue("test_task", durable=> True );
sub run-routes() is export { ... }

错误信息:

===SORRY!===
No such method 'open-channel' for invocant of type 'Any'

谢谢!

4

2 回答 2

4

当您定义您的可导出路由函数时,您可以指定参数,然后在您的组合模块中您可以创建共享对象并将它们传递给路由。例如在您的路由器模块中:

sub run-routes ($rmq) is export{
    route {
       ... $rmq is available in here
    }
}

然后在您的主路由器中,您可以创建队列并在包含时将其传入

my $rmq = # Insert queue creation code here
include product => run-routes( $rmq );

我没有尝试过,但我看不出它不应该工作的任何原因。

于 2018-10-21T16:31:06.657 回答
1

@Scimon 的答案当然是正确的,但它没有解决 OP。另一方面,@ugexe 和@raiph 的两条评论很贴切,所以我会尝试在这里总结它们并解释发生了什么。

错误本身

这是错误:

错误信息:

===抱歉!=== 对于“任何”类型的调用者,没有这种方法“开放通道”

它表明调用者 ( $XXX::YYY::rabbitConnection) 是 type Any,这是通常在变量没有定义值时分配给变量的类型;也就是说,基本上$XXX::YYY::rabbitConnection没有定义。XXX::YYY正如@ugexe 所指出的,它肯定不是因为它不包含在导入的模块中。

OP指出的其他问题

该模块已从导入列表中删除,因为如OP 所示

我当然用错误的方式编码,因为如果我尝试添加 use XXX::YYY;,我得到一个循环模块加载检测错误

但是当然。因为use XXX::YYY::Route1;这是文件 2,所以包含在文件 1 中。

最终的解决方案是重新组织文件

这种循环依赖可能表明它们应该在同一个文件中,否则公共代码应该被分解到第三个文件中,最终将被两者包含。所以你应该有类似单元模块 XXX::YYY::Common; 使用 Net::AMQP;

our $rabbitConnection is export = Net::AMQP.new;
await $rabbitConnection.connect;

接着

use XXX::YYY::Common;

在两个模块中。

于 2018-12-08T18:13:46.683 回答