运行Laravel队列时出现过程问题

时间:2019-12-16 05:30:57

标签: php laravel apache2

我想通过队列执行Laravel作业,但是我找不到在队列为空时启动队列和调用方法的好方法。

我的控制器为我的客户生成菜单(word文件),在他们创建之后,我想将所有文件下载到一个zip文件夹下。

因此过程如下:

1-用户单击前端的按钮创建我的客户菜单

2-作业被分派到队列中(生成当天的所有菜单)

3-队列开始

4-当队列为空时,直接将文件下载到用户的浏览器

总结一切,我在所有进程之间存在同步问题。我不知道如何启动队列以及如何调用将下载新生成的文件的方法。

这是我到目前为止所做的:

在我的控制器中:

    public function menusEdition(Request $request){

    $date = $request->date;
    $day = DB::table('days')->where('calendarDate','=',$date)->pluck('day')[0];

    $menus = Menu::where('day',$day)->get();

    foreach($menus as $menu){
        $job = new MenusEdition($menu);
        $this->dispatch($job);
    }

    Artisan::call('queue:work --stop-when-empty');

    $this->downloadDayMenus($date);     //Method that downloads all the menus of the day

    return back();
}

public function downloadDayMenus($date){
    $folderPath = storage_path('app\public\archived-menus\\'.$date);

    $rootPath = realpath($folderPath);

    $zip = new ZipArchive();
    $zipName = $rootPath.'/'.$date.'-menus.zip';
    $zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE);

    // Create recursive directory iterator
    /** @var SplFileInfo[] $files */
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($rootPath),
        RecursiveIteratorIterator::LEAVES_ONLY
    );

    foreach ($files as $name => $file)
    {
        // Skip directories (they would be added automatically)
        if (!$file->isDir())
        {
            // Get real and relative path for current file
            $filePath = $file->getRealPath();
            $relativePath = substr($filePath, strlen($rootPath) + 1);

            // Add current file to archive
            $zip->addFile($filePath, $relativePath);
        }
    }

    // Zip archive will be created only after closing object
    $zip->close();

    return response()->download($zipName);
}

从我的工作“ MenuEdition”开始:

class MenusEdition implements ShouldQueue
{
  use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

  protected $menu;

  /**
   * Create a new job instance.
   *
   * @return void
   */
  public function __construct($menu)
  {
      $this->menu = $menu;
  }

  /**
   * Execute the job.
   *
   * @return void
   */
  public function handle(MenusController $menusController)
  {
      $menu = $this->menu;
      $menuFile = $menusController->templateEdition($menu->id);
      return;
  }

}

备注:出于某种原因,在调用artisan命令之后,用户将被重定向到空白页...

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

队列是异步的,这意味着它将在后台而不是在请求期间进行处理。这意味着用户无法直接与队列结果进行交互。但是,您可能会想到类似的替代方法

  • 队列完成处理后,将菜单邮寄给用户
  • 在您的UI中添加一个按钮,队列完成处理后即可启用

如果您希望菜单被同步处理,那么您不应该使用队列。