示例#1
0
func listenForResponse(topic string, partition int32, batch []*ProducerRecord, responseChan <-chan *rawResponseAndError) {
	response := <-responseChan
	if response.err != nil {
		for _, record := range batch {
			record.metadataChan <- &RecordMetadata{Record: record, Error: response.err}
		}
	}

	decoder := siesta.NewBinaryDecoder(response.bytes)
	produceResponse := new(siesta.ProduceResponse)
	decodingErr := produceResponse.Read(decoder)
	if decodingErr != nil {
		for _, record := range batch {
			record.metadataChan <- &RecordMetadata{Record: record, Error: decodingErr.Error()}
		}
	}

	status, exists := produceResponse.Status[topic][partition]
	if exists {
		currentOffset := status.Offset
		for _, record := range batch {
			record.metadataChan <- &RecordMetadata{
				Record:    record,
				Topic:     topic,
				Partition: partition,
				Offset:    currentOffset,
				Error:     status.Error,
			}
			currentOffset++
		}
	}
}
示例#2
0
func (nc *NetworkClient) trySend(request *siesta.ProduceRequest, batch []*ProducerRecord) error {
	leader, err := nc.connector.GetLeader(nc.Topic, nc.Partition)
	if err != nil {
		return err
	}

	response := <-nc.selector.Send(leader, request)
	if response.sendErr != nil {
		err = nc.connector.Metadata().Refresh([]string{nc.Topic})
		if err != nil {
			Logger.Warn("Send error occurred, returning it but also failed to refresh metadata: %s", err)
		}
		return response.sendErr
	}

	if nc.RequiredAcks == 0 {
		// acks = 0 case, just complete all requests
		for _, record := range batch {
			record.metadataChan <- &RecordMetadata{
				Record:    record,
				Offset:    -1,
				Topic:     nc.Topic,
				Partition: nc.Partition,
				Error:     siesta.ErrNoError,
			}
		}
		return nil
	}

	if response.receiveErr != nil {
		err = nc.connector.Metadata().Refresh([]string{nc.Topic})
		if err != nil {
			Logger.Warn("Receive error occurred, returning it but also failed to refresh metadata: %s", err)
		}
		return response.receiveErr
	}

	decoder := siesta.NewBinaryDecoder(response.bytes)
	produceResponse := new(siesta.ProduceResponse)
	decodingErr := produceResponse.Read(decoder)
	if decodingErr != nil {
		return decodingErr.Error()
	}

	status, exists := produceResponse.Status[nc.Topic][nc.Partition]
	if exists {
		if status.Error == siesta.ErrNotLeaderForPartition {
			err = nc.connector.Metadata().Refresh([]string{nc.Topic})
			if err != nil {
				Logger.Warn("Produce error occurred, returning it but also failed to refresh metadata: %s", err)
			}
			return status.Error
		}

		currentOffset := status.Offset
		for _, record := range batch {
			record.metadataChan <- &RecordMetadata{
				Record:    record,
				Topic:     nc.Topic,
				Partition: nc.Partition,
				Offset:    currentOffset,
				Error:     status.Error,
			}
			currentOffset++
		}
	}

	return nil
}