예제 #1
0
 /**
  * Modify task in queue
  * @param Task $task
  * @throws Exceptions\QueueException
  * @return Task
  */
 public function modify_task($task)
 {
     if (!$task instanceof Task) {
         return false;
     }
     $need_commit = false;
     if ($task->have_subtasks()) {
         $need_commit = true;
         $database_data = $this->driver->prepare_modify($task->get_uniqid());
         if (is_null($database_data)) {
             throw new QueueException('Task for modify not found');
         }
         foreach ($database_data as $id => $task_database_data) {
             /**
              * @var Task $modify_task
              */
             $current_task = $id == 0 ? $task : $task->sub_tasks()->get($task_database_data[TaskConst::UNIQID]);
             $current_task_data = $current_task->to_array();
             //check not modified parameters
             foreach ($this->not_modifiable_parameters as $not_modifiable_parameter) {
                 if ($current_task_data[$not_modifiable_parameter] != $task_database_data[$not_modifiable_parameter]) {
                     throw new QueueException("Parameter {$not_modifiable_parameter} was changed");
                 }
             }
             $diff = array_diff($current_task_data, $task_database_data);
             $current_task->set_array($diff);
         }
         $task->set_subtasks_quantity_not_performed(0)->set_subtasks_error(0);
         $have_in_process = false;
         foreach ($task->sub_tasks()->get_all() as $sub_task) {
             if ($sub_task->get_status() == Task::STATUS_IN_PROCESS) {
                 $have_in_process = true;
             }
             switch ($sub_task->get_status()) {
                 case Task::STATUS_CALLBACK_ERROR:
                     $task->completed_error(Task::STATUS_CALLBACK_ERROR);
                 case Task::STATUS_ERROR:
                     $task->inc_subtasks_error();
                     if ($sub_task->settings()->get_nested_settings('error_break')) {
                         $task->completed_error();
                     }
                     break;
                 case Task::STATUS_NEW:
                     $task->inc_subtasks_quantity_not_performed();
                     break;
             }
         }
         if (!$have_in_process && $task->get_subtasks_quantity_not_performed() == 0 && !in_array($task->get_status(), array(Task::STATUS_ERROR, Task::STATUS_CALLBACK_ERROR))) {
             if ($task->get_subtasks_error() > 0) {
                 $task->completed_error(Task::STATUS_DONE_WITH_ERROR);
             } else {
                 $task->completed_ok();
             }
         }
         $this->driver->modify_task($task->sub_tasks()->get_perform_task());
     }
     $this->driver->modify_task($task, $need_commit);
     return $task;
 }
예제 #2
0
 /**
  * SetUp tasks in queue
  */
 public static function setUpBeforeClass()
 {
     static::prepareTestExecution();
     self::$queue = new \PhpQueue\Queue(static::getQueueDriver());
     self::$task_performer1 = new \PhpQueue\TaskPerformer();
     self::$task_performer2 = new \PhpQueue\TaskPerformer(self::EXCLUSIVE_PERFORMER);
     //one task
     $task = new Task(self::JOB, self::TASK_ARGS);
     $task->set_callback(self::TASK_JOB_CALLBACK)->set_error_callback(self::TASK_JOB_CALLBACK);
     self::$queue->add_task($task);
     //task with sub tasks
     $task = new Task(self::JOB, self::TASK_ARGS);
     $task->set_callback(self::TASK_JOB_CALLBACK)->set_error_callback(self::TASK_JOB_CALLBACK);
     for ($i = 0; $i < self::TASKS_COUNT_5; $i++) {
         $sub_task = new Task(self::JOB_1, $i);
         $sub_task->set_callback(self::SUB_TASK_JOB_CALLBACK)->set_error_callback(self::SUB_TASK_JOB_CALLBACK);
         $task->sub_tasks()->add($sub_task);
     }
     self::$queue->add_task($task);
     //task with sub tasks and error break false and exclusive
     $task = new Task(self::JOB_2);
     $task->set_callback(self::TASK_JOB_CALLBACK)->set_error_callback(self::TASK_JOB_CALLBACK)->set_exclusive(true);
     for ($i = 0; $i < self::TASKS_COUNT_3; $i++) {
         $sub_task = new Task(self::JOB_2, $i);
         $task->sub_tasks()->add($sub_task);
     }
     self::$queue->add_task($task);
     //task with error
     $task = new Task(self::JOB);
     $task->set_callback(self::TASK_JOB_CALLBACK)->set_error_callback(self::TASK_JOB_CALLBACK)->settings()->set_error_break(false)->set_error_max_trial(self::TASKS_COUNT_3);
     for ($i = 0; $i < self::TASKS_COUNT_5; $i++) {
         if ($i == 2) {
             $sub_task = new Task(self::ERROR_JOB, $i);
         } else {
             $sub_task = new Task(self::JOB_2, $i);
         }
         $task->sub_tasks()->add($sub_task);
     }
     self::$queue->add_task($task);
     //task with subtasks and error
     $task = new Task(self::JOB);
     $task->set_task_group_id(2)->settings()->set_error_break(true)->set_error_max_trial(2);
     $sub_task = new Task(self::ERROR_JOB);
     $task->sub_tasks()->add($sub_task);
     for ($i = 0; $i < 3; $i++) {
         $sub_task = new Task(self::JOB_2, $i);
         $task->sub_tasks()->add($sub_task);
     }
     self::$queue->add_task($task);
     $task = new Task(self::ERROR_JOB);
     $task->set_task_group_id(3);
     self::$queue->add_task($task);
 }
예제 #3
0
 /**
  * Execute task
  * @param Task $task
  * @return Task
  */
 public function execute_task($task)
 {
     if (!$task instanceof Task) {
         return false;
     }
     if (is_null($task->get_start_date())) {
         $task->set_start_date(date('Y-m-d H:i:s'));
     }
     $task->set_performer($this->performer_name);
     if ($task->have_subtasks()) {
         if (!$task->get_exclusive()) {
             $task->null_performer();
         }
         $this->execute_task($task->sub_tasks()->get_perform_task());
         return $task;
     }
     $callback_classes_founded = $task->check_callback_class_names();
     if (!$callback_classes_founded) {
         $task->set_status(Task::STATUS_ERROR);
         return $task;
     }
     $exec_array = $this->default_job_priority;
     for ($job_id = 0; $job_id < count($exec_array); $job_id++) {
         /**
          * @var \PhpQueue\Interfaces\IJob|\PhpQueue\Interfaces\ICallback|\PhpQueue\Interfaces\IErrorCallback
          */
         $exec_class = null;
         $job_type = $exec_array[$job_id];
         switch ($job_type) {
             case TaskConst::JOB:
                 $exec_class = $task->get_task_name();
                 break;
             case TaskConst::TASK_CALLBACK:
                 $exec_class = $task->get_callback();
                 break;
             case TaskConst::PARENT_CALLBACK:
                 $exec_class = $task->get_parent_callback();
                 break;
             case TaskConst::GLOBAL_CALLBACK:
                 $exec_class = $this->get_global_callback();
                 break;
             case TaskConst::TASK_ERROR_CALLBACK:
                 $exec_class = $task->get_error_callback();
                 break;
             case TaskConst::PARENT_ERROR_CALLBACK:
                 $exec_class = $task->get_parent_error_callback();
                 break;
             case TaskConst::GLOBAL_ERROR_CALLBACK:
                 $exec_class = $this->get_global_error_callback();
                 break;
         }
         if (is_null($exec_class)) {
             continue;
         }
         $method_name = $this->interface_methods[Helper::interface_job($job_type)];
         try {
             $response = call_user_func_array(array($exec_class, $method_name), array($task));
             if ($job_type == TaskConst::JOB) {
                 $task->completed_ok()->response()->set_response($response);
             }
         } catch (\Exception $exception) {
             $task->response()->set_error($exception->getMessage() . " File: " . $exception->getFile() . " Line: " . $exception->getLine());
             if ($job_type != TaskConst::JOB) {
                 $task->set_status(Task::STATUS_CALLBACK_ERROR);
                 break;
             }
             $job_id = 0;
             $exec_array = $this->default_error_job_priority;
             if ($task->settings()->get_trial() >= $task->settings()->get_nested_settings('error_max_trial')) {
                 $task->completed_error();
             } else {
                 $task->set_status(Task::STATUS_NEW)->settings()->inc_trial();
             }
         }
     }
     return $task;
 }
예제 #4
0
 /**
  * Get data from data provider, generate and return task
  * @param array $request
  * @return mixed
  */
 public function get_task(array $request)
 {
     $request = array_filter($request);
     if (array_key_exists(TaskConst::UNIQID, $request)) {
         $request[TaskConst::NEED_SET_IN_PROCESS_FLAG] = false;
     }
     $this->lock_file();
     $xml_dom = $this->get_xml_dom();
     $result = call_user_func(function () use($xml_dom, $request) {
         $head_task = $this->xpath_find($xml_dom, $request);
         if (is_null($head_task)) {
             return false;
         }
         //select task from file
         $head_task_array = $this->get_task_array_from_file((string) $head_task[TaskConst::UNIQID]);
         if ($request[TaskConst::NEED_SET_IN_PROCESS_FLAG]) {
             //set status for task and index record
             if ((int) $head_task[TaskConst::STATUS] == Task::STATUS_NEW) {
                 $head_task[TaskConst::STATUS] = Task::STATUS_IN_PROCESS;
                 $head_task_array[TaskConst::STATUS] = Task::STATUS_IN_PROCESS;
             }
             if ((int) $head_task[TaskConst::SUBTASKS_QUANTITY_NOT_PERFORMED] > 0) {
                 $head_task[TaskConst::SUBTASKS_QUANTITY_NOT_PERFORMED] = (int) $head_task[TaskConst::SUBTASKS_QUANTITY_NOT_PERFORMED] - 1;
                 $head_task_array[TaskConst::SUBTASKS_QUANTITY_NOT_PERFORMED]--;
             }
             $this->save_array($head_task_array);
         }
         $task = new Task($head_task_array);
         // select sub tasks
         if (!property_exists($head_task, self::SUB_TASKS_XML)) {
             $this->save_xml_dom($xml_dom);
             return $task;
         }
         $perform_id = null;
         $sub_tasks = array();
         foreach ($head_task->{self::SUB_TASKS_XML}->{self::TASK_XML} as $sub_task) {
             $sub_task = (array) $sub_task;
             $sub_tasks[] = $sub_task['@attributes'];
         }
         unset($sub_task);
         if ($request[TaskConst::NEED_SET_IN_PROCESS_FLAG]) {
             foreach ($sub_tasks as $sub_task) {
                 if ((int) $sub_task[TaskConst::STATUS] != Task::STATUS_NEW) {
                     continue;
                 }
                 $sub_task[TaskConst::STATUS] = Task::STATUS_IN_PROCESS;
                 $sub_task_array = $this->get_task_array_from_file($sub_task[TaskConst::UNIQID]);
                 $sub_task_array[TaskConst::STATUS] = Task::STATUS_IN_PROCESS;
                 $this->save_array($sub_task_array);
                 $perform_id = $sub_task[TaskConst::UNIQID];
                 break;
             }
         }
         foreach ($sub_tasks as $sub_task) {
             $sub_task_params = $this->get_task_array_from_file($sub_task[TaskConst::UNIQID]);
             if ($perform_id == $sub_task[TaskConst::UNIQID]) {
                 $task->sub_tasks()->add_perform_task(new Task($sub_task_params));
                 continue;
             }
             $task->sub_tasks()->add(new Task($sub_task_params));
         }
         $this->save_xml_dom($xml_dom);
         return $task;
     });
     $this->release_file();
     return $result;
 }
예제 #5
0
 /**
  * Get data from data provider, generate and return task
  * @param array $request
  * @return mixed
  */
 public function get_task(array $request)
 {
     $request = array_filter($request);
     $this->connection->beginTransaction();
     $task = call_user_func(function () use($request) {
         if (array_key_exists(TaskConst::UNIQID, $request)) {
             $request[TaskConst::NEED_SET_IN_PROCESS_FLAG] = false;
         }
         $head_task = $this->select_task($request);
         if (!$head_task) {
             return false;
         }
         $task = new Task($head_task);
         if ($head_task[TaskConst::SUBTASKS_QUANTITY] > 0) {
             $sub_task_request = array(TaskConst::PARENT_ID => $head_task[TaskConst::UNIQID], TaskConst::NEED_SET_IN_PROCESS_FLAG => $request[TaskConst::NEED_SET_IN_PROCESS_FLAG]);
             $sub_tasks = $this->select_sub_task($sub_task_request);
             if (!empty($sub_tasks['sub_tasks'])) {
                 foreach ($sub_tasks['sub_tasks'] as $sub_task) {
                     if ($sub_task[TaskConst::UNIQID] == $sub_tasks['perform_task']) {
                         $task->sub_tasks()->add_perform_task(new Task($sub_task));
                         continue;
                     }
                     $task->sub_tasks()->add(new Task($sub_task));
                 }
             }
         }
         return $task;
     });
     $this->connection->commit();
     return $task;
 }