Example #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++
		}
	}
}
Example #2
0
func (s *Selector) receive(conn *net.TCPConn) ([]byte, error) {
	conn.SetReadDeadline(time.Now().Add(s.config.ReadTimeout))
	header := make([]byte, 8)
	_, err := io.ReadFull(conn, header)
	if err != nil {
		return nil, err
	}

	decoder := siesta.NewBinaryDecoder(header)
	length, err := decoder.GetInt32()
	if err != nil {
		return nil, err
	}
	response := make([]byte, length-4)
	_, err = io.ReadFull(conn, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}
Example #3
0
func decodeErr(t *testing.T, response siesta.Response, bytes []byte, expected *siesta.DecodingError) {
	decoder := siesta.NewBinaryDecoder(bytes)
	err := response.Read(decoder)
	assert(t, err.Error(), expected.Error())
	assert(t, err.Reason(), expected.Reason())
}
Example #4
0
func decode(t *testing.T, response siesta.Response, bytes []byte) {
	decoder := siesta.NewBinaryDecoder(bytes)
	err := response.Read(decoder)
	assert(t, err, (*siesta.DecodingError)(nil))
}
Example #5
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
}