2016-02-16 4 views
1

У меня есть работа symfony, которая имеет две функции: запуск и остановка. Моя функция запуска импортирует контакты, например, 4 на 4 из базы данных и отправляет их всем сообщениям.прервать функцию другой функцией

public function launchAction() 
{ 
    $offset = 0; 
    $limit = 4; 
    $sizeData /= $limit; 

    for($i = 0; $i < $sizeData; $i++) 
    { 
     $contacts = $repository->getListByLimit($offset, $limit); 
     $sender->setContacts($contacts); 
     $sender->send(); 
     $offset += $limit; 
    } 
} 

, когда я начал свою функцию запуска потребуется, например, 20 секунд, чтобы импортировать и отправить сообщение всем контактам , но если я хочу, чтобы остановить его, как может функция останова прерывают функция Launch

public function stopAction() 
{ 

} 
+1

Он не может ..... особенно как каждый запрос запускается в своем собственном независимом потоке, и поэтому они не могут взаимодействовать с другими потоками –

+1

@Alaeddine - Но stopAction не может работать, если запущен цикл launchAction –

+0

@MarkBaker я могу что-то сделать в loopAction, как класс Evloop, чтобы остановить цикл? – Devilion

ответ

1

Если только цели состоит в том, чтобы быть в состоянии остановить сценарий, вам не нужно полное выполнение петлевого события, я думаю. Вы можете прослушивать локальный сокет и прерываться при получении данных.

Вы могли бы, например, запустить это в launchAction

public function launchAction() 
{ 
    $offset = 0; 
    $limit = 4; 
    $sizeData /= $limit; 

    // Init IPC connection 
    $server = stream_socket_server("tcp://127.0.0.1:1337", $errno, $errorMessage); 
    if ($server === false) { 
     throw new UnexpectedValueException("Could not bind to socket: $errorMessage"); 
    } 

    for($i = 0; $i < $sizeData; $i++) 
    { 
     // Check our socket for data 
     $client = @stream_socket_accept($server); 
     if ($client) { 
      // Read sent data 
      $data = fread($client, 1024); 

      // Probably break 
      if ($data === 'whatever') { 
       break; 
      } 
     } 

     $contacts = $repository->getListByLimit($offset, $limit); 
     $sender->setContacts($contacts); 
     $sender->send(); 
     $offset += $limit; 
    } 

    // Close socket after sending all messages 
    fclose($client); 
} 

И stopAction может ударить сокет разорвать соединение следующим образом:

public function stopAction() 
{ 
    $socket = stream_socket_client('tcp://127.0.0.1:1337'); 

    fwrite($socket, 'whatever'); 

    fclose($socket); 
} 

Это должно работать, если вы запускаете обе функции на том же машина. Также обратите внимание, что PHP может слушать только сокеты, которые уже не заняты. Поэтому вам может потребоваться изменить номер порта. И если вы начнете второй процесс отправки сообщений параллельно, новый не сможет связываться с одним и тем же сокетом.

Большой Блогпост объяснить некоторые детали является https://www.christophh.net/2012/07/24/php-socket-programming/

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

Вы можете посмотреть на этой BlogPost серии, чтобы получить представление о https://blog.wyrihaximus.net/2015/01/reactphp-introduction/

+0

спасибо, могу я спросить вас что-то еще? – Devilion

+0

Просто спросите, я могу отказаться позже :) – martinczerwi

+0

Если я хочу снова отправить отправку, что я могу сделать, чтобы функция запуска могла узнать последний идентификатор контакта и снова запустить. – Devilion

2

я не буду полностью ответить, но дать вам две подсказки, как это может работать

1:

сохранить файл с идентификатором процесса в Лос-Анджелесе УНЧ()

на остановке() можно проверить наличие и убить процесс по идентификатору

2:

на старте(), вы можете проверить наличие определенной БД-записи в цикле, так что нарушает если значение присутствует

на остановке установить эту запись DB

+0

Вариант 3, откройте разъем UNIX и прослушайте соединения, которые завершают цикл. Но в целом форма сохранения, например.файл или ввод базы данных проще реализовать – martinczerwi

+0

@john Smith Я могу что-то сделать в launchAction, как класс Evloop, чтобы остановить цикл? – Devilion

+0

жаль, что у меня нет опыта работы с Evloop –

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