我在一个相当大的Mojolicious应用程序上工作,它需要很多秒来编译。
该应用程序的部分测试套件是使用playwright编写的,它目前为每个测试用例建立了一个原始数据库,并使用@mojolicious/server-starter
生成了mojolicious应用程序的一个示例。
应用程序的编译时间已经开始使大幅扩展playwright测试套件变得不切实际,我想在不给予隔离测试数据库和mojolicious应用程序示例的情况下解决这个问题。
为了实现这一点,我目前追求的想法是拥有一个小的perl应用程序,它可以预加载较大的Mojolicious应用程序,并且剧作家测试套件可以要求它在一个开放端口上使用原始数据库产生较大应用程序的新示例。
我希望使用HTTP与较小Perl应用程序通信,这主要是出于方便,而且我希望较小的Perl应用程序使用Mojolicious来执行HTTP通信,因为这也很方便,而且与代码库的其余部分一致。
我尝试过一些简单的方法来实现这个想法,大致如下:
use TheBigApp;
$app->routes->post('/spawn-child')->to(cb => sub ($c) {
my ($sock, $port) = new_listen_socket();
if (my $pid = fork()) {
# record pid to later be able to shut it down or whatever
$c->render(json => { url => "http://localhost:$port" })
} else {
my $bapp = TheBigApp->new($c->req->json);
my $s = Mojo::Server::Daemon->new(listen => ...);
$s->app($bapp);
$bapp->start;
return;
}
});
我沿着这些路线尝试的所有实现似乎都遇到了由于各种单例(如IOLoop)而导致的问题,什至当覆盖IOLoop->singleton
以在子进程中返回具有新React器的新示例时,派生的子进程似乎仍在与派生它们的父进程监听同一个套接字。
是否有更低级别的Mojolicious API可以让这个用例工作?在没有Mojolicious的情况下实现小的父进程是否会更简单,从而完全回避这个问题?
谢谢你!
1条答案
按热度按时间qco9c6ql1#
在Mojo服务器/守护程序代码中稍微挖掘一下,它总是(?)在IO::Socket上设置“ReusePort”。
在linux上(不是macOS或BSD,我不知道windows),这意味着到同一IP和端口组合的TCP连接是由内核在多个服务器示例上“负载平衡”的。
从您的帖子中还不清楚派生的进程是否在同一端口上侦听。
假设您运行的是linux,更改每个派生子进程的监听端口可能会有所帮助。