Laravel Queue Worker 无法解析动态单例绑定
Laravel dynamic singleton binding can't resolve by Queue Worker
在我的 Laravel 应用程序中,我必须进行第三方 API 调用,因此我将所有与第三方相关的详细信息存储在数据库中( URL 和密码, ETC。 )。为了让这个客户端在应用程序的任何地方都可用,我创建了服务提供者
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 并注册单例 class。应用程序用户还可以从 UI 添加新的第三方,所以现在为了制作单例,我将相同的代码与单个 $thirdParty
.
问题
因此,当添加新的第三方时,应用程序将分派一个作业,我在其中使用相同 class 的相同 Singleton 实例。但是由于 Laravel 容器中的动态绑定,我的工作人员不知道如何解决这个问题并开始失败。
PS:重启 Queue worker 后一切正常。
感谢任何帮助或替代方法。
谢谢。
如果你 运行 你的队列工作器,它 运行 总是在后台(如果你有像 Supervisor 这样的监控进程),所以它会在第一次注册单例,如果你添加more Third-parties 之后,它将不再加载任何内容。因此,当您重新启动队列工作程序时,它就会开始工作。
您可以在 Laravel 文档中看到此建议,https://laravel.com/docs/5.8/queues#running-the-queue-worker
Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers.
希望对你有所帮助
此致。
如@Clemen 所述,队列工作者是一个 long-lived 进程,它是一个 PHP 实例,并且在您部署应用程序时已经启动了该应用程序。
每次第三方创建、更新和删除时,我都建议您 运行 Artisan::call('queue:restart')
。您可以通过使用 Model Events 或在 APIs(Controller).
中手动执行此操作来实现此目的
当您更新它们时也存在问题,这是因为 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');
});
}
}
在我的 Laravel 应用程序中,我必须进行第三方 API 调用,因此我将所有与第三方相关的详细信息存储在数据库中( URL 和密码, ETC。 )。为了让这个客户端在应用程序的任何地方都可用,我创建了服务提供者
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 并注册单例 class。应用程序用户还可以从 UI 添加新的第三方,所以现在为了制作单例,我将相同的代码与单个 $thirdParty
.
问题
因此,当添加新的第三方时,应用程序将分派一个作业,我在其中使用相同 class 的相同 Singleton 实例。但是由于 Laravel 容器中的动态绑定,我的工作人员不知道如何解决这个问题并开始失败。
PS:重启 Queue worker 后一切正常。
感谢任何帮助或替代方法。 谢谢。
如果你 运行 你的队列工作器,它 运行 总是在后台(如果你有像 Supervisor 这样的监控进程),所以它会在第一次注册单例,如果你添加more Third-parties 之后,它将不再加载任何内容。因此,当您重新启动队列工作程序时,它就会开始工作。
您可以在 Laravel 文档中看到此建议,https://laravel.com/docs/5.8/queues#running-the-queue-worker
Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers.
希望对你有所帮助
此致。
如@Clemen 所述,队列工作者是一个 long-lived 进程,它是一个 PHP 实例,并且在您部署应用程序时已经启动了该应用程序。
每次第三方创建、更新和删除时,我都建议您 运行 Artisan::call('queue:restart')
。您可以通过使用 Model Events 或在 APIs(Controller).
当您更新它们时也存在问题,这是因为 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');
});
}
}