如何在cro中的两个路由器模块之间共享变量?

时间:2018-10-19 20:20:03

标签: perl6 cro

我尝试使用Cro创建一个Rest API,该API将在RabbitMQ中发布消息。我想将路线分为不同的模块,并用“ include”组成。但是我也希望能够在每个模块中共享与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'

谢谢!

2 个答案:

答案 0 :(得分: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 );

我还没有尝试过,但是我看不出为什么它不起作用。

答案 1 :(得分:1)

@Scimon的回答肯定是正确的,但它没有解决OP。另一方面,@ ugexe和@raiph的两个注释是即时出现的,因此,我将在这里尝试对其进行总结,并说明发生了什么。

错误本身

这是错误:

  

错误消息:

     

===抱歉!===对于“ Any”类型的倡导者,没有这样的“开放渠道”方法

它指示主体($XXX::YYY::rabbitConnection)的类型为Any,这是通常在变量没有定义值时分配给它们的类型;也就是说,基本上没有定义$XXX::YYY::rabbitConnection。当然不是,因为@ugexe指示XXX::YYY没有包含在导入的模块中。

OP指出的其他问题

该模块已从导入列表中删除,因为它是indicated by the OP

  

我当然用错误的方式编码,因为如果我尝试增加使用   XXX :: YYY ;,我收到检测到循环模块加载错误

但是,当然。因为文件1中包含了use XXX::YYY::Route1;(即文件2)。

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

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

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

然后

use XXX::YYY::Common;
在两个模块中为