如何在 Laravel 5.1 中运行时更改队列驱动程序?

4

我使用beanstalkd作为我的队列驱动程序:

# /.env
QUEUE_DRIVER=beanstalkd

# /config/queue.php
'default' => env('QUEUE_DRIVER', 'sync'),

和可排队的作业

# /app/Jobs/MyJob.php
class MyJob extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    ....
    ....
}

当我通过控制器分发作业时,这个方法非常有效,但是我希望在分发作业时,有一条特定的路由使用同步驱动程序而不是beanstalkd驱动程序。中间件似乎是这里的答案。

# /app/Http/Controllers/MyController.php
public function create(Request $request)
{
    $this->dispatch(new \App\Jobs\MyJob());
}

# /app/Http/routes.php
Route::post('/create', ['middleware' => 'no_queue', 'uses' => 'MyController@create']);

# /app/Http/Middleware/NoQueue.php
public function handle($request, Closure $next)
{
    $response = $next($request);
    config(['queue.default'=>'sync']);
    return $response;
}

然而,该工作仍被推送到beanstalkd队列。

换句话说,在从控制器调度作业时如何在运行时更改队列驱动程序?

编辑: 从艺术家命令中调用config(['queue.default'=>'sync'])似乎可以工作,但从Http控制器中不起作用...

# /app/Conosle/Commands/MyCommand.php

class ScrapeDrawing extends Command
{
    use DispatchesJobs;
    ...
    ...
    public function handle()
    {
        config(['queue.default'=>'sync'])
        $this->dispatch(new \App\Jobs\MyJob());
    }
}

1
Queue::driver('sync')->push(new \App\Jobs\MyJob()); 这个怎么样? - ceejayoz
Call to undefined method Illuminate\Queue\Queue::driver() - divups
2个回答

3

在我控制器方法中使用以下代码解决了问题:

# /app/Http/Controllers/MyController.php
public function create(Request $request, QueueManager $queueManager)

    $defaultDriver = $queueManager->getDefaultDriver();

    $queueManager->setDefaultDriver('sync');

    \Queue::push(new \App\Jobs\MyJob());

    $queueManager->setDefaultDriver($defaultDriver);
}

在我的情况下,\Queue:push() 似乎会注意到运行时的驱动程序更改,而 $this->dispatch() 则不会。

1

看一下你的中间件做了什么 - $next($request); 这段代码执行请求。正如你所看到的,你是在请求已经处理完之后才改变配置。请更改。

public function handle($request, Closure $next)
{
  $response = $next($request);
  config(['queue.default'=>'sync']);
  return $response;
}

to

public function handle($request, Closure $next)
{
  config(['queue.default'=>'sync']);
  $response = $next($request);
  return $response;
}

很好的发现,但还是没有成功。工作仍在被推送到beanstalkd。 - divups
你确定吗?我在我们的中间件中这样做过,它可以工作 - 我使用了SyncQueue对象而不是数据库队列。你是如何检查使用哪个队列的? - jedrzej.kurylo
我看到作业正在ptrofimov/beanstalk_console中处理。你在.env文件中设置了队列驱动程序吗? - divups

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接