如何在 cro 中的两个路由器模块之间共享变量?
How to share a variable between two routers module in cro?
我尝试使用 Cro 创建一个将在 rabbitMQ 中发布消息的 Rest API。我想将我的路线分成不同的模块,并用 "include" 组合它们。但我也希望能够在每个模块中共享与 rabbitMQ 的相同连接。我尝试使用 "our" 但它不起作用:
文件 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'
谢谢!
当您定义可导出的路由函数时,您可以指定参数,然后在您的组合模块中您可以创建共享对象并将它们传递给路由。例如在你的路由器模块中:
sub run-routes ($rmq) is export{
route {
... $rmq is available in here
}
}
然后在你的主路由器中你可以创建你的队列并在包含时将其传入
my $rmq = # Insert queue creation code here
include product => run-routes( $rmq );
我没有试过这个,但我看不出有任何原因它不应该工作。
@Scimon 的回答当然是正确的,但它没有解决 OP。另一方面,@ugexe 和@raiph 的两条评论是准确的,所以我将尝试在这里总结它们并解释发生了什么。
错误本身
这是错误:
Error message:
===SORRY!=== No such method 'open-channel' for invocant of type 'Any'
表示调用者($XXX::YYY::rabbitConnection
)的类型为Any
,这是通常赋值给没有定义值的变量的类型;也就是说,基本上 $XXX::YYY::rabbitConnection
没有定义。当然不是,因为 XXX::YYY
不包含在导入的模块中,如@ugexe 所示。
OP 指出的其他问题
该模块已从导入列表中删除,因为
I certainly code it the wrong way because if i try to add use
XXX::YYY;, i get a Circular module loading detected error
当然可以。因为文件 2 use XXX::YYY::Route1;
包含在文件 1 中。
最后的解决办法是重新整理文件
循环依赖可能指出了它们应该在同一个文件中的事实,否则公共代码应该被分解到第三个文件中,最终将被两个文件包含。所以你应该有类似的东西
单元模块XXX::YYY::Common;
使用 Net::AMQP;
our $rabbitConnection is export = Net::AMQP.new;
await $rabbitConnection.connect;
然后
use XXX::YYY::Common;
在两个模块中。
我尝试使用 Cro 创建一个将在 rabbitMQ 中发布消息的 Rest API。我想将我的路线分成不同的模块,并用 "include" 组合它们。但我也希望能够在每个模块中共享与 rabbitMQ 的相同连接。我尝试使用 "our" 但它不起作用:
文件 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'
谢谢!
当您定义可导出的路由函数时,您可以指定参数,然后在您的组合模块中您可以创建共享对象并将它们传递给路由。例如在你的路由器模块中:
sub run-routes ($rmq) is export{
route {
... $rmq is available in here
}
}
然后在你的主路由器中你可以创建你的队列并在包含时将其传入
my $rmq = # Insert queue creation code here
include product => run-routes( $rmq );
我没有试过这个,但我看不出有任何原因它不应该工作。
@Scimon 的回答当然是正确的,但它没有解决 OP。另一方面,@ugexe 和@raiph 的两条评论是准确的,所以我将尝试在这里总结它们并解释发生了什么。
错误本身
这是错误:
Error message:
===SORRY!=== No such method 'open-channel' for invocant of type 'Any'
表示调用者($XXX::YYY::rabbitConnection
)的类型为Any
,这是通常赋值给没有定义值的变量的类型;也就是说,基本上 $XXX::YYY::rabbitConnection
没有定义。当然不是,因为 XXX::YYY
不包含在导入的模块中,如@ugexe 所示。
OP 指出的其他问题
该模块已从导入列表中删除,因为
I certainly code it the wrong way because if i try to add use XXX::YYY;, i get a Circular module loading detected error
当然可以。因为文件 2 use XXX::YYY::Route1;
包含在文件 1 中。
最后的解决办法是重新整理文件
循环依赖可能指出了它们应该在同一个文件中的事实,否则公共代码应该被分解到第三个文件中,最终将被两个文件包含。所以你应该有类似的东西 单元模块XXX::YYY::Common; 使用 Net::AMQP;
our $rabbitConnection is export = Net::AMQP.new;
await $rabbitConnection.connect;
然后
use XXX::YYY::Common;
在两个模块中。