2015-08-18 2 views
0

Я использую Gearman и тонкий PHP для создания RESTful API, в котором:обработка Gearman параллельно и дать выходной intermedeate

Пользователь будет вызывать успокоительной API и отправить файл URL. Это будет тогда:

  1. Скачать файл - и отправить пользователю уникальный идентификатор файла в качестве ответа HTTP
  2. Поскольку ответ посылается, я хочу, чтобы начать обработку файла
  3. Пользователь может проверить состояние процесса GET www.example.com/api/status API-вызов

Я использовал механизм, чтобы сделать нормальный для части загрузки файла, но ответ на состояние отправляется только после того, как обработка выполнена. Также, как получить статус каждого клиентского процесса? Мне нужна дополнительная помощь в том, как именно я мог бы структурировать те же самые и несколько подробностей о quering обработке, поскольку я новичок в gearman.

ответ

0

Вам необходимо использовать jobstatus и doBackground(). Во-первых, вам необходимо инициализировать передачу. Это делается путем отправки задачи на задний план и отправки пользователю дескриптора задания. Вы вызываете это через yourserver.com/api/file-transfer и должны отправить запрос POST с файлом set. Ответ - это json-объект.

<?php 
// use composer for slim 
require_once "vendor/autoload.php"; 
$app = new \Slim\Slim(); 

// init file transfer 
$app->post('/file-transfer', function() use ($app) { 
    $resp = array(); 
    try { 
     // get file url 
     $fileurl = $app->request->post('fileurl'); 
     $data = json_encode(array("fileurl"=>$fileurl); 

     // send to gearman 
     $client = new GearmanClient(); 
     $client->addServer(); 

     // store the gearman handle and send the task to the background 
     $jobHandle = $client->doBackground("fileUpload", $data); 

     if ($client->returnCode() != GEARMAN_SUCCESS) throw new Exception("Could not add the job to the queue.", 1); 

     $resp["msg"] = "File upload queued"; 
     $resp["handle"] = $jobHandle; 
    } catch(Exception $e) { 
     // some error handling 
     $resp["msg"] = "There occured a strange error."; 
     $resp["error"] = true; 
    } finally { 
     $response = $app->response(); 
     $response['Content-Type'] = 'application/json'; 
     $response->status(200); 
     $response->body(json_encode($resp));  
    } 
}); 
?> 

На втором этапе пользователь должен обращаться к серверу с ручкой задания (которое он получил от первого звонка):

$app->post('/file-status', function() use ($app) { 
    $jobHandle = $app->request->params('handle'); 
    $resp = array(); 
    try { 
     // ask for job status 
     $client = new GearmanClient(); 
     $client->addServer(); 
     $stat = $client->jobStatus($jobHandle); 
     if (!$stat[0]) { // it is done 
      $resp["msg"] = "Transfer completed."; 
     } else { 
      $resp["msg"] = "Transfer in progress."; 
      $w = (float)$stat[2]; // calculate the percentage 
      $g = (float)$stat[3]; 
      $p = ($g>0)?$w/g*100:0; 
      $resp["percentage"] = $p; 
     } 
    } catch(Exception $e) { 
      // some error handling 
      $resp["msg"] = "There occured a strange error."; 
      $resp["error"] = true; 
    } finally { 
     $response = $app->response(); 
     $response['Content-Type'] = 'application/json'; 
     $response->status(200); 
     $response->body(json_encode($resp));  
    } 
}); 

Во втором запросе, у вас есть массив $ Статистика из $ client-> jobStatus(). $ stats [0] сообщает вам, известно ли задание серверу передач. Второй лемент проверяет, работает ли он, и три и четыре (2/3) используются для расчета процента передачи (вам нужно сами установить эти значения!).

+0

Да, какой-то код действительно поможет. Я не могу отправить ответ, а затем продолжить процесс после него. –

+0

. Я понимаю, однако, я хочу повторить ответ пользователю после завершения загрузки файла. Затем запустите новый процесс (для обработки загруженного файла), для которого я хочу показать пользователю статус. Статус не должен использоваться для API загрузки файлов. –

+0

К сожалению, [обратные вызовы не работают в фоновых заданиях] (http://stackoverflow.com/questions/21656299/gearman-addtaskbackground-complete-callback-doesnot-fire) в Gearman. Поэтому возможным решением было бы использовать [jquery ajax] (http://api.jquery.com/jquery.ajax/) и опросить сервер каждые пять-десять секунд, пока обработка не будет выполнена. – Jan

Смежные вопросы