public function run($queueItemId, $lastFseekPosition = 0)
 {
     Yii::$app->response->format = Response::FORMAT_JSON;
     /** @var DeferredQueue $item */
     $item = DeferredQueue::loadModel($queueItemId, false, false, 0, new NotFoundHttpException());
     if ($item->status === DeferredQueue::STATUS_SCHEDULED || $item->status === DeferredQueue::STATUS_DISABLED) {
         return new ReportingTaskResponse(['status' => $item->status]);
     } else {
         if (empty($item->output_file)) {
             return new ReportingTaskResponse(['error' => true, 'errorMessage' => Yii::t('deferred-tasks', 'Field output_file is empty for queue item.')]);
         }
         if (file_exists($item->output_file) && is_readable($item->output_file)) {
             $fp = fopen($item->output_file, 'r');
             $stat = fstat($fp);
             $fseekStatus = fseek($fp, $lastFseekPosition);
             if ($fseekStatus !== 0) {
                 fclose($fp);
                 return new ReportingTaskResponse(['error' => true, 'errorMessage' => Yii::t('deferred-tasks', 'Unable to fseek file.'), 'lastFseekPosition' => $lastFseekPosition, 'newOutput' => '', 'status' => $item->status, 'nextQueue' => $item->next_task_id]);
             }
             $bytesToRead = $stat['size'] - $lastFseekPosition;
             if ($bytesToRead > 0) {
                 $data = fread($fp, $bytesToRead);
             } else {
                 $data = '';
             }
             $lastFseekPosition += $bytesToRead;
             fclose($fp);
             return new ReportingTaskResponse(['status' => $item->status, 'nextQueue' => $item->next_task_id, 'error' => false, 'newOutput' => $data, 'lastFseekPosition' => $lastFseekPosition, 'taskStatusCode' => $item->exit_code]);
         } else {
             return new ReportingTaskResponse(['error' => true, 'errorMessage' => Yii::t('deferred-tasks', 'Error accessing output file.'), 'lastFseekPosition' => $lastFseekPosition, 'newOutput' => '', 'status' => $item->status, 'nextQueue' => $item->next_task_id]);
         }
     }
 }
 public function actionReport($id, $code)
 {
     /** @var DeferredQueue $item */
     $item = DeferredQueue::loadModel($id);
     if ($item === null) {
         $this->stderr("No such item {$id}");
     }
     $item->exit_code = $code;
     $item->save();
     // trigger event
 }
 public function testReportingChain()
 {
     $files = ['task201', 'task202'];
     $testChain = new ReportingChain();
     $this->assertTrue(false === $testChain->registerTask());
     foreach ($files as $f) {
         if (file_exists("/tmp/{$f}")) {
             unlink("/tmp/{$f}");
         }
         $testTask = new ReportingTask();
         $testTask->cliCommand('touch', "/tmp/{$f}");
         $testChain->addTask($testTask);
     }
     $firstTaskId = $testChain->registerChain();
     $this->assertTrue($firstTaskId !== null);
     $time = time() + 120;
     Yii::$app->runAction('deferred/index', [$firstTaskId, $time, 1]);
     /** @var DeferredQueue $finishedTask */
     $finishedTask = DeferredQueue::loadModel($firstTaskId);
     $this->assertEquals(DeferredQueue::STATUS_SUCCESS_AND_NEXT, $finishedTask->status);
     $this->assertTrue(file_exists('/tmp/task201'));
 }