Laravel动态单例绑定无法由Queue Worker解析

时间:2019-06-12 09:09:40

标签: php laravel laravel-5.8 laravel-queue

在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后,一切似乎都正常运行。

任何帮助或其他方式都值得赞赏。 谢谢。

2 个答案:

答案 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');
        });
    }
}