在Laravel应用程序中,我必须进行第三方API调用,因此我将与第三方相关的所有详细信息存储在数据库中(URL和密码等)。为了使该客户端对应用程序中的任何地方都可用,我创建了服务提供商
ServiceProvider.php
$thirdParties = ThirdParty::all();
collect($thirdParties)->each(function ($thirdParty) {
$this->app->singleton(Str::snake($thirdParty->name), function ($app) use($thirdParty) {
$config = new Config();
$config->setLoginUrl($thirdParty->auth_url)
->setUsername($thirdParty->username)
->setPassword($thirdParty->password);
$client = new Client($config);
$client->Login();
return $client;
});
});
提供程序的所有工作文件都将获取所有Thrid Patry并注册单例类。应用程序用户还可以从UI添加新的第三方,因此现在要使该单例代码与单$thirdParty
相同。
问题
因此,当添加新的第三方时,应用程序将调度一个Job,在其中我利用相同类的相同Singleton实例。但是由于Laravel Container中的动态绑定,我的工作人员不知道如何解决该问题并开始失败。
PS:重新启动Queue worker后,一切似乎都正常运行。
任何帮助或其他方式都值得赞赏。 谢谢。
答案 0 :(得分:1)
如果您运行Queue worker,它总是在后台运行(如果您有像Supervisor这样的监视程序),因此它第一次注册单例,如果之后添加更多的第三方,则不会加载更多的东西。因此,当您重新启动队列工作器时,它会开始工作。
您可以在Laravel文档https://laravel.com/docs/5.8/queues#running-the-queue-worker
中看到此建议请记住,队列工作器是长期存在的进程,并将启动的应用程序状态存储在内存中。因此,启动它们后,他们将不会注意到代码库中的更改。因此,在部署过程中,请确保重新启动队列工作器。
希望对您有帮助。
致谢。
答案 1 :(得分:1)
如@Clemen所述,队列工作器是一个长期存在的进程,它是一个PHP实例,并且在部署应用程序时该应用程序已被引导。
我建议您每次创建,更新和删除ThirdParty时都运行Artisan::call('queue:restart')
。您可以使用Model Events或在API(控制器)中手动完成此操作。
更新它们时也存在问题,这是因为API的凭据仍然过时,因此必须在创建,更新和删除时进行操作。
示例:
class ThirdParty extends Model
{
protected static function boot()
{
parent::boot();
static::creating(function (ThirdParty $thirdParty) {
Artisan::call('queue:restart');
});
static::updating(function (ThirdParty $thirdParty) {
Artisan::call('queue:restart');
});
static::deleted(function (ThirdParty $thirdParty) {
Artisan::call('queue:restart');
});
}
}