%PDF- %PDF-
Direktori : /www/varak.net/wiki.varak.net/vendor/nmred/kafka-php/src/Kafka/ |
Current File : //www/varak.net/wiki.varak.net/vendor/nmred/kafka-php/src/Kafka/Produce.php |
<?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */ // +--------------------------------------------------------------------------- // | SWAN [ $_SWANBR_SLOGAN_$ ] // +--------------------------------------------------------------------------- // | Copyright $_SWANBR_COPYRIGHT_$ // +--------------------------------------------------------------------------- // | Version $_SWANBR_VERSION_$ // +--------------------------------------------------------------------------- // | Licensed ( $_SWANBR_LICENSED_URL_$ ) // +--------------------------------------------------------------------------- // | $_SWANBR_WEB_DOMAIN_$ // +--------------------------------------------------------------------------- namespace Kafka; /** +------------------------------------------------------------------------------ * Kafka protocol since Kafka v0.8 +------------------------------------------------------------------------------ * * @package * @version $_SWANBR_VERSION_$ * @copyright Copyleft * @author $_SWANBR_AUTHOR_$ +------------------------------------------------------------------------------ */ class Produce { // {{{ consts // }}} // {{{ members /** * client * * @var mixed * @access private */ private $client = null; /** * send message options cache * * @var array * @access private */ private $payload = array(); /** * default the server will not send any response * * @var float * @access private */ private $requiredAck = 0; /** * default timeout is 100ms * * @var float * @access private */ private $timeout = 100; /** * produce instance * * @var \Kafka\Produce * @access private */ private static $instance = null; // }}} // {{{ functions // {{{ public function static getInstance() /** * set send messages * * @access public * @param $hostList * @param $timeout * @param null $kafkaHostList * @return Produce */ public static function getInstance($hostList, $timeout, $kafkaHostList = null) { if (is_null(self::$instance)) { self::$instance = new self($hostList, $timeout, $kafkaHostList); } return self::$instance; } // }}} // {{{ public function __construct() /** * __construct * * @access public * @param $hostList * @param null $timeout * @param null $kafkaHostList */ public function __construct($hostList, $timeout = null, $kafkaHostList = null) { if ($hostList instanceof \Kafka\ClusterMetaData) { $metadata = $hostList; } elseif ( $kafkaHostList !== null ) { $metadata = new \Kafka\MetaDataFromKafka($kafkaHostList); } else { $metadata = new \Kafka\ZooKeeper($hostList, $timeout); } $this->client = new \Kafka\Client($metadata); } // }}} // {{{ public function setMessages() /** * set send messages * * @access public * @param $topicName * @param int $partitionId * @param array $messages * @return Produce */ public function setMessages($topicName, $partitionId = 0, $messages = array()) { if (isset($this->payload[$topicName][$partitionId])) { $this->payload[$topicName][$partitionId] = array_merge($this->payload[$topicName][$partitionId], $messages); } else { $this->payload[$topicName][$partitionId] = $messages; } return $this; } // }}} // {{{ public function setRequireAck() /** * set request mode * This field indicates how many acknowledgements the servers should receive * before responding to the request. If it is 0 the server will not send any * response (this is the only case where the server will not reply to a * request). If it is 1, the server will wait the data is written to the * local log before sending a response. If it is -1 the server will block * until the message is committed by all in sync replicas before sending a * response. For any number > 1 the server will block waiting for this * number of acknowledgements to occur (but the server will never wait for * more acknowledgements than there are in-sync replicas). * * @param int $ack * @access public * @return Produce */ public function setRequireAck($ack = 0) { if ($ack >= -1) { $this->requiredAck = (int) $ack; } return $this; } // }}} // {{{ public function setTimeOut() /** * set request timeout * * @param int $timeout * @access public * @return Produce */ public function setTimeOut($timeout = 100) { if ((int) $timeout) { $this->timeout = (int) $timeout; } return $this; } // }}} // {{{ public function send() /** * send message to broker * * @access public * @return bool|array */ public function send() { $data = $this->_formatPayload(); if (empty($data)) { return false; } $responseData = array(); foreach ($data as $host => $requestData) { $stream = $this->client->getStream($host); $conn = $stream['stream']; $encoder = new \Kafka\Protocol\Encoder($conn); $encoder->produceRequest($requestData); if ((int) $this->requiredAck !== 0) { // get broker response $decoder = new \Kafka\Protocol\Decoder($conn); $response = $decoder->produceResponse(); foreach ($response as $topicName => $info) { if (!isset($responseData[$topicName])) { $responseData[$topicName] = $info; } else { $responseData[$topicName] = array_merge($info, $responseData[$topicName]); } } } $this->client->freeStream($stream['key']); } $this->payload = array(); return $responseData; } // }}} // {{{ public function getClient() /** * get client object * * @access public * @return Client */ public function getClient() { return $this->client; } /** * passthru method to client for setting stream options * * @access public * @param array $options */ public function setStreamOptions($options = array()) { $this->client->setStreamOptions($options); } // }}} // {{{ public function getAvailablePartitions() /** * get available partition * * @access public * @param $topicName * @return array */ public function getAvailablePartitions($topicName) { $topicDetail = $this->client->getTopicDetail($topicName); if (is_array($topicDetail) && isset($topicDetail['partitions'])) { $topicPartitiions = array_keys($topicDetail['partitions']); } else { $topicPartitiions = array(); } return $topicPartitiions; } // }}} // {{{ private function _formatPayload() /** * format payload array * * @access private * @return array */ private function _formatPayload() { if (empty($this->payload)) { return array(); } $data = array(); foreach ($this->payload as $topicName => $partitions) { foreach ($partitions as $partitionId => $messages) { $host = $this->client->getHostByPartition($topicName, $partitionId); $data[$host][$topicName][$partitionId] = $messages; } } $requestData = array(); foreach ($data as $host => $info) { $topicData = array(); foreach ($info as $topicName => $partitions) { $partitionData = array(); foreach ($partitions as $partitionId => $messages) { $partitionData[] = array( 'partition_id' => $partitionId, 'messages' => $messages, ); } $topicData[] = array( 'topic_name' => $topicName, 'partitions' => $partitionData, ); } $requestData[$host] = array( 'required_ack' => $this->requiredAck, 'timeout' => $this->timeout, 'data' => $topicData, ); } return $requestData; } // }}} // }}} }