2015-02-15 2 views
3

Я запускаю задачу с большим сроком выполнения, которая возвращает инкрементный вывод о ходе выполнения задач компонентом Symfony Process.Ajax-опрос с компонентом Symfony Process

Один из примеров показывает, как получить вывод в реальном времени, а другой пример показывает, как запускать асинхронную задачу.

Я пытаюсь достичь результата getIncrementalOutput обратно в функцию опроса ajax, поэтому я могу обновить интерфейс в реальном времени.

Кажется, в любом случае процесс-> start() блокируется, потому что мой вызов ajax занимает минуту, чтобы вернуться, и к тому времени задача завершилась.

Я думаю, я пытаюсь избежать записи прогресса в db или файл и получить результат непосредственно из выполняемой задачи PHP.

Не уверен, что это возможно.

+1

Я мог бы быть неправильно, но я думаю, что это порождает подпроцесс основной PHP прок, поэтому с точки зрения запроса жизненного цикла его еще блокирующим, это как раз не блокировать другие вещи, которые вы, возможно, захотите сделать в ходе этого запроса. Вы не можете запустить подпрограмму ... вернуть ответ, а затем использовать второй запрос, чтобы проверить его. Для этого вам понадобится какая-то очередь. – prodigitalson

+0

А я понимаю, что вы имеете в виду. Это может быть так – paul

ответ

4

Хотя я не совсем понимаю, что вы хотите создать, я написал что-то подобное и, глядя на него может ответить на ваш вопрос:

Сначала я создал команду, которая делает затянувшуюся задачу:

class GenerateCardBarcodesCommand extends Command 
{ 
    protected function configure() 
    { 
     $this 
      ->setName('app:generate-card-barcodes') 
      ->setDescription('Generate the customer cards with barcodes') 
      ->addArgument('id', InputArgument::REQUIRED, 'id of the Loy/Card entity') 
     ; 
    } 

    protected function execute(InputInterface $input, OutputInterface $output) 
    { 
     $id = $input->getArgument('id'); 
     // generate stuff and put them in the database 
    } 
} 

в контроллере запускается процесс и есть действие Ajax

class CardController extends Controller 
{ 
    public function newAction(Request $request) 
    { 
       // run command in background to start generating barcodes 
       // NOTE: unset DYLD_LIBRARY_PATH is a fix for MacOSX develop using MAMP. 
       // @see http://stackoverflow.com/questions/19008960/phantomjs-on-mac-os-x-works-from-the-command-line-not-via-exec 
       $process = new Process(sprintf('unset DYLD_LIBRARY_PATH ; php ../../apps/spin/console spin:loy:generate-card-barcodes %d', $entity->getId())); 
       $process->start(); 

       sleep(1); // wait for process to start 

       // check for errors and output them through flashbag 
       if (!$process->isRunning()) 
        if (!$process->isSuccessful()) 
         $this->get('session')->getFlashBag()->add('error', "Oops! The process fininished with an error:".$process->getErrorOutput()); 

       // otherwise assume the process is still running. It's progress will be displayed on the card index 
       return $this->redirect($this->generateUrl('loy_card')); 
    } 

    public function ajaxCreateBarcodesAction($id) 
    { 
     $em = $this->getDoctrine()->getManager(); 
     $entity = $this->getEntity($id); 
     $count = (int)$em->getRepository('ExtendasSpinBundle:Loy\CustomerCard')->getCount($entity); 
     return new Response(floor($count/($entity->getNoCards()/100))); 
    } 
} 

// в шаблоне ветку на основе AJAX извлекается, который просто число от 0 до 100, которое используется в jquery ui progressbar. {{ «Обработка» | транс}} ...

  <script type="text/javascript"> 
      $(function() { 
       function pollLatestResponse() { 
        $.get("{{ path('loy_card_ajax_generate_barcodes', {'id': entity[0].id}) }}").done(function (perc) { 
         if (perc == 100) 
         { 
          clearInterval(pollTimer); 
          $('#download-{{entity[0].id}}').show(); 
          $('#progress-{{entity[0].id}}').hide(); 
         } 
         else 
         { 
          $('#progress-{{entity[0].id}}').progressbar("value", parseInt(perc)); 
         } 
        }); 
       } 

       var pollTimer; 
       $(document).ready(function() { 
        $('#progress-{{entity[0].id}}').progressbar({"value": false}); 
        pollTimer = setInterval(pollLatestResponse, 2000); 
       }); 
      }); 
      </script> 
Смежные вопросы