예제 #1
0
 /**
  * @param Job $job
  * @param TaskResult $taskResult
  * @return TaskResult
  */
 private function executeJobTask(Job $job, TaskResult $taskResult)
 {
     $stopwatchEvent = $this->stopwatch->start($taskResult->getId(), 'task');
     $logger = new TaskLogger($job, $taskResult->getTask(), $this->storageApi);
     $logger->start($stopwatchEvent);
     $startTime = time();
     try {
         $this->fillComponentData($taskResult);
         $httpClient = new Client(array(), $this->logger);
         $response = $httpClient->sendOrchestratorRequest($job, $taskResult->getTask(), $this->encryptor);
         $pollResponse = null;
         // handling async task
         if (ResponseValidator::isAsyncResponse($response)) {
             $taskJobUrl = null;
             try {
                 $data = ResponseDecoder::decode($response);
                 if (!empty($data['url'])) {
                     $taskJobUrl = $data['url'];
                 }
             } catch (\Exception $e) {
             }
             if ($taskJobUrl) {
                 $taskResult->setJobUrl($taskJobUrl);
                 $this->saveJobResult($this->jobResult);
             }
             $this->logTaskUsability($taskResult, $response);
             $retriesCount = 1;
             $timeout = $taskResult->getTimeoutMinutes() ? $taskResult->getTimeoutMinutes() : KeboolaOrchestratorBundle::TIMEOUT_MINUTES;
             // polling job
             do {
                 $data = array('status' => 'unknown');
                 if (time() >= $startTime + $timeout * 60) {
                     throw new Exception\JobRuntimeException(sprintf('Asynchronous task processing timeout after %d minutes', $timeout));
                 }
                 $waitSeconds = min(pow(2, $retriesCount), 20);
                 sleep($waitSeconds);
                 try {
                     $pollResponse = $httpClient->sendOrchestratorPollRequest($job, $response, $this->encryptor, $retriesCount);
                     if ($pollResponse) {
                         $data = ResponseDecoder::decode($pollResponse);
                     }
                 } catch (GuzzleException\RequestException $e) {
                     if ($e instanceof Exception\CurlException) {
                     } else {
                         $prevE = $e->getPrevious();
                         if (!$prevE || !$prevE instanceof Exception\JobRuntimeException) {
                             throw $e;
                         }
                     }
                 } catch (\Exception $e) {
                     // maybe json decode error, do nothing
                 }
                 $retriesCount++;
             } while (array_key_exists('status', $data) && !StatusConverter::isFinishedStatus($data['status']));
         } else {
             // stats log
             if (ResponseValidator::isSuccessfulResponse($response) || ResponseValidator::isInformationalResponse($response)) {
                 $this->logTaskUsability($taskResult, $response);
             }
         }
         if ($pollResponse) {
             $response = $pollResponse;
             if (empty($data) || !in_array($data['status'], array('success', 'ok'))) {
                 //@TODO logovat odpovedi, ktere vraci nesmyslne OK status
                 $fakeRequest = new Request($pollResponse ? 'GET' : 'POST', $response->getHeaderLine(Client::EFFECTIVE_URL_HEADER_NAME));
                 $clientExc = new GuzzleException\ClientException('Error response from component', $fakeRequest, $response);
                 throw $clientExc;
             }
         }
         if (!ResponseValidator::isSuccessfulResponse($response) && !ResponseValidator::isInformationalResponse($response)) {
             $fakeRequest = new Request($pollResponse ? 'GET' : 'POST', $response->getHeaderLine(Client::EFFECTIVE_URL_HEADER_NAME));
             $clientExc = new GuzzleException\ClientException('Response with error HTTP code', $fakeRequest, $response);
             throw $clientExc;
         }
         $endEvent = $logger->end();
     } catch (GuzzleException\ClientException $e) {
         $endEvent = $logger->clientError($e);
         if ($e->getResponse()) {
             $response = $e->getResponse();
         }
     } catch (GuzzleException\BadResponseException $e) {
         $endEvent = $logger->responseError($e);
         if ($e->getResponse()) {
             $response = $e->getResponse();
         }
     } catch (\Exception $e) {
         $endEvent = $logger->someError($e, $this->logger);
         $response = null;
     }
     $taskResult->setResult($endEvent, empty($response) ? null : $response);
     return $taskResult;
 }
예제 #2
0
 /**
  * @param Phase $phase
  * @return Response[]
  */
 public function startPhase(Phase $phase, PhaseLogger $logger, Client $httpClient)
 {
     /**
      * @var Response[] $jobResponses
      */
     $jobResponses = array();
     // create jobs
     foreach ($phase->getTasks() as $taskResult) {
         // skip inactive tasks
         if (!$taskResult->getTask()->getActive()) {
             continue;
         }
         $endEvent = null;
         try {
             $taskResult->setProcessingStatus();
             $this->jobResult->addTaskResult($taskResult);
             $this->saveJobResult($this->jobResult);
             $stopwatchEvent = $this->stopwatch->start($taskResult->getId(), 'task');
             $this->fillComponentData($taskResult);
             $logger->getLogger($taskResult)->start($stopwatchEvent);
             $response = $httpClient->sendOrchestratorRequest($phase->getJob(), $taskResult->getTask(), $this->encryptor);
             //				if (!ResponseValidator::isAsyncResponse($response)) {
             //					throw new UserException('Parallel task processing does not support synchronous components', null, array(
             //						'component' => $taskResult->getComponent(),
             //						'componentUrl' => $taskResult->getComponentUrl(),
             //						'action' => $taskResult->getAction(),
             //					));
             //				}
             $taskJobUrl = null;
             try {
                 $data = ResponseDecoder::decode($response);
                 if (!empty($data['url'])) {
                     $taskJobUrl = $data['url'];
                 }
             } catch (\Exception $e) {
             }
             if ($taskJobUrl) {
                 $taskResult->setJobUrl($taskJobUrl);
                 $this->saveJobResult($this->jobResult);
             }
             if (count($phase->getTasks()) > 1) {
                 $this->logParallelTaskUsability($taskResult, $response);
             } else {
                 $this->logTaskUsability($taskResult, $response);
             }
             $jobResponses[$taskResult->getId()] = $response;
         } catch (GuzzleException\ClientException $e) {
             $endEvent = $logger->getLogger($taskResult)->clientError($e);
             if ($e->getResponse()) {
                 $response = $e->getResponse();
             }
         } catch (GuzzleException\BadResponseException $e) {
             $endEvent = $logger->getLogger($taskResult)->responseError($e);
             if ($e->getResponse()) {
                 $response = $e->getResponse();
             }
         } catch (\Exception $e) {
             $endEvent = $logger->getLogger($taskResult)->someError($e, $this->logger);
             $response = null;
         }
         if ($endEvent) {
             $taskResult->setResult($endEvent, empty($response) ? null : $response);
             $this->saveJobResult($this->jobResult);
         }
         if ($taskResult->getError() && !$taskResult->getTask()->getContinueOnFailure()) {
             return false;
         }
     }
     return $jobResponses;
 }