/** * get consumer offset * * @param integer $defaultOffset * if defaultOffset -1 instead of early offset * if defaultOffset -2 instead of last offset * @access public * @return void */ public function getOffset($defaultOffset = self::DEFAULT_LAST) { $maxOffset = $this->getProduceOffset(self::LAST_OFFSET); $minOffset = $this->getProduceOffset(self::EARLIEST_OFFSET); $data = array('group_id' => $this->groupId, 'data' => array(array('topic_name' => $this->topicName, 'partitions' => array(array('partition_id' => $this->partitionId))))); $this->encoder->fetchOffsetRequest($data); $result = $this->decoder->fetchOffsetResponse(); $this->client->freeStream($this->streamKey); $topicName = $this->topicName; $partitionId = $this->partitionId; if (!isset($result[$topicName][$partitionId]['errCode'])) { throw new \Kafka\Exception('fetch topic offset failed.'); } if ($result[$topicName][$partitionId]['errCode'] == 3) { switch ($defaultOffset) { case self::DEFAULT_LAST: return $maxOffset; Log::log("topic name: {$topicName}, partitionId: {$partitionId}, get offset value is default last.", LOG_INFO); case self::DEFAULT_EARLY: Log::log("topic name: {$topicName}, partitionId: {$partitionId}, get offset value is default early.", LOG_INFO); return $minOffset; default: $this->setOffset($defaultOffset); Log::log("topic name: {$topicName}, partitionId: {$partitionId}, get offset value is default {$defaultOffset}.", LOG_INFO); return $defaultOffset; } if ($defaultOffset) { $this->setOffset($defaultOffset); return $defaultOffset; } } elseif ($result[$topicName][$partitionId]['errCode'] == 0) { $offset = $result[$topicName][$partitionId]['offset']; if ($offset > $maxOffset || $offset < $minOffset) { if ($defaultOffset == self::DEFAULT_EARLY) { $offset = $minOffset; } else { $offset = $maxOffset; } } Log::log("topic name: {$topicName}, partitionId: {$partitionId}, get offset value is {$offset}.", LOG_INFO); return $offset; } else { throw new \Kafka\Exception(\Kafka\Protocol\Decoder::getError($result[$topicName][$partitionId]['errCode'])); } }
/** * load next partition * * @access public * @return bool */ public function loadNextPartition() { if ($this->validCount >= $this->partitionCount) { return false; } try { $partitionId = $this->stream->read(4, true); $partitionId = Decoder::unpack(Decoder::BIT_B32, $partitionId); $partitionId = array_shift($partitionId); \Kafka\Log::log("kafka client:fetch partition:" . $partitionId, LOG_INFO); $errCode = $this->stream->read(2, true); $errCode = Decoder::unpack(Decoder::BIT_B16, $errCode); $this->errCode = array_shift($errCode); if ($this->errCode != 0) { throw new \Kafka\Exception(\Kafka\Protocol\Decoder::getError($this->errCode)); } $offset = $this->stream->read(8, true); $this->offset = \Kafka\Protocol\Decoder::unpack(Decoder::BIT_B64, $offset); $this->key = $partitionId; $this->current = new MessageSet($this, $this->context); } catch (\Kafka\Exception $e) { \Kafka\Log::log($e->getMessage(), LOG_ERR); return false; } $this->validCount++; return true; }
/** * set topic partition * * @access public * @param $topicName * @param int $partitionId * @param null $offset * @return Consumer */ public function setPartition($topicName, $partitionId = 0, $offset = null) { if (is_null($offset)) { if ($this->fromOffset) { $offsetObject = new \Kafka\Offset($this->client, $this->group, $topicName, $partitionId); $offset = $offsetObject->getOffset($this->offsetStrategy); \Kafka\Log::log('topic name:' . $topicName . ', part:' . $partitionId . 'get offset from kafka server, offet:' . $offset, LOG_DEBUG); } else { $offset = 0; } } $this->payload[$topicName][$partitionId] = $offset; return $this; }
/** * load next message * * @access public * @return void */ public function loadNextMessage() { if ($this->validByteCount >= $this->messageSetSize) { return false; } try { if ($this->validByteCount + 12 > $this->messageSetSize) { // read socket buffer dirty data $this->stream->read($this->messageSetSize - $this->validByteCount); return false; } $offset = $this->stream->read(8, true); $this->offset = \Kafka\Protocol\Decoder::unpack(Decoder::BIT_B64, $offset); $messageSize = $this->stream->read(4, true); $messageSize = Decoder::unpack(Decoder::BIT_B32, $messageSize); $messageSize = array_shift($messageSize); $this->validByteCount += 12; if ($this->validByteCount + $messageSize > $this->messageSetSize) { // read socket buffer dirty data $this->stream->read($this->messageSetSize - $this->validByteCount); return false; } $msg = $this->stream->read($messageSize, true); $this->current = new Message($msg); } catch (\Kafka\Exception $e) { \Kafka\Log::log("already fetch: {$this->validByteCount}, {$e->getMessage()}", LOG_INFO); return false; } $this->validByteCount += $messageSize; return true; }