duanrebo3559 2016-02-16 13:05
浏览 16
已采纳

通过其他功能中断功能

i have a symfony job that have two function: launch and stop. My launch function will import contacts,for example 4 by 4 from database and send to all of them messages.

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;
    }
}

when i launched my launch function it will take for example 20 seconds to import and send the message to all contacts but if i want to stop it,how can the stop function interrupt the launch function

public function stopAction()
{

}
  • 写回答

2条回答 默认 最新

  • dounie0889 2016-02-16 17:13
    关注

    If your only purpose is to be able to stop the script, you don't need a full event loop implementation I think. You can listen to a local socket, and break when you receive data.

    You could for example run this in 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);
    }
    

    And stopAction could hit the socket to terminate the connection like so:

    public function stopAction()
    {
        $socket = stream_socket_client('tcp://127.0.0.1:1337');
    
        fwrite($socket, 'whatever');
    
        fclose($socket);
    }
    

    This should work if you run both functions on the same machine. Also note that PHP can only listen to sockets which are not occupied already. So you might need to change the port number. And in case you start a second process to send messages in parallel, the new one will not be able to bind to the same socket.

    A great blogpost explaining some detail is https://www.christophh.net/2012/07/24/php-socket-programming/

    If however you wish to start a long running process, I suggest you take a look at ReactPHP, which is an excellent event loop implementation that runs on several different setups. It also includes timers, and other useful libs.

    You might want to take a look at this blogpost series, to get an idea https://blog.wyrihaximus.net/2015/01/reactphp-introduction/

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?