/**
  * @inheritdoc
  * @param DeferredQueue $queue
  * @param array $config
  */
 public function __construct(&$queue, $group = null, $config = [])
 {
     parent::__construct($queue->deferred_group_id, $queue->id, $config);
     $this->queue = $queue;
     $this->group = $group;
     $this->success = $this->queue->getProcess()->getExitCode() === 0;
 }
 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 testGetNextTasks()
 {
     $time = mktime(19, 40, 0, 5, 19, 2015);
     $tasks = DeferredQueue::getNextTasks($time);
     $disabledTaskExists = false;
     $futureTaskExists = false;
     foreach ($tasks as $task) {
         if ($task->id === 1) {
             $disabledTaskExists = true;
         }
         if ($task->id === 2) {
             $futureTaskExists = true;
         }
     }
     $this->assertTrue($disabledTaskExists === false);
     $this->assertTrue($futureTaskExists === false);
 }
 public function __construct($attributes = [])
 {
     $this->model = new DeferredQueue();
     $this->model->initiated_date = date("Y-m-d H:i:s");
     $this->model->setAttributes($attributes);
 }
 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
 }
 /**
  * @param integer $currentTime
  * @param array   $ids Filter by ids
  * @return DeferredQueue[]
  */
 public static function getNextTasks($currentTime, $ids = null)
 {
     $currentTime = date("Y-m-d H:i:s", $currentTime);
     $query = DeferredQueue::find()->where(['status' => DeferredQueue::STATUS_SCHEDULED]);
     if ($ids !== null) {
         $query = $query->andWhere(['in', 'id', (array) $ids]);
     } else {
         $query = $query->andWhere('next_start <= :next_start', [':next_start' => $currentTime]);
     }
     return $query->orderBy(['id' => SORT_ASC])->all();
 }
 /**
  * Sends immediate notification if needed
  * @param DeferredGroup $group
  * @param DeferredQueue $item
  */
 private function immediateNotification(&$group, &$item)
 {
     $item->complete();
     $immediateNotification = false;
     if (is_object($group) === true) {
         if (intval($group->group_notifications) === 0) {
             $immediateNotification = true;
         }
     } else {
         $immediateNotification = true;
     }
     if ($immediateNotification === true) {
         $this->trigger('deferred-queue-complete', new DeferredQueueCompleteEvent($item));
     }
 }
 public function testQueueCompleteEventHandler()
 {
     $files = ['task401', 'task402'];
     $testChain = new ReportingChain();
     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();
     DeferredHelper::runImmediateTask($firstTaskId);
     sleep(2);
     $this->assertTrue(file_exists('/tmp/task401'));
     /** @var DeferredQueue $queue */
     $queue = DeferredQueue::findOne(['id' => $firstTaskId]);
     $process = new Process('pwd > /dev/null');
     $process->run();
     $queue->setProcess($process);
     $event = new DeferredQueueCompleteEvent($queue);
     QueueCompleteEventHandler::handleEvent($event);
     sleep(2);
     $this->assertTrue(file_exists('/tmp/task402'));
 }
 public function down()
 {
     $this->dropColumn(DeferredQueue::tableName(), 'next_task_id');
 }
 public function testHandleBadQueue()
 {
     TestConfigCleaner::removeExtFile();
     $this->assertFalse(TestConfigCleaner::checkExtFile());
     Yii::setAlias('@vendor', realpath(__DIR__ . '/../../testapp/vendor'));
     $group = new DeferredGroup();
     $group->loadDefaultValues();
     $group->name = ExtensionsManager::ACTIVATE_DEFERRED_TASK;
     $group->group_notifications = 0;
     $group->save();
     $queue = new DeferredQueue([]);
     $queue->deferred_group_id = $group->id;
     $process = new Process('pwd > /dev/null');
     $process->run();
     $queue->setProcess($process);
     $queue->exit_code = 1;
     $event = new DeferredQueueCompleteEvent($queue);
     DeferredQueueCompleteHandler::handleEvent($event);
     $this->assertFalse(TestConfigCleaner::checkExtFile());
 }