github.com/rbisecke/kafka-go@v0.4.27/txnoffsetcommit.go (about)

     1  package kafka
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"time"
     8  
     9  	"github.com/rbisecke/kafka-go/protocol/txnoffsetcommit"
    10  )
    11  
    12  // TxnOffsetCommitRequest represents a request sent to a kafka broker to commit
    13  // offsets for a partition within a transaction.
    14  type TxnOffsetCommitRequest struct {
    15  	// Address of the kafka broker to send the request to.
    16  	Addr net.Addr
    17  
    18  	// The transactional id key.
    19  	TransactionalID string
    20  
    21  	// ID of the consumer group to publish the offsets for.
    22  	GroupID string
    23  
    24  	// The Producer ID (PID) for the current producer session;
    25  	// received from an InitProducerID request.
    26  	ProducerID int
    27  
    28  	// The epoch associated with the current producer session for the given PID
    29  	ProducerEpoch int
    30  
    31  	// GenerationID is the current generation for the group.
    32  	GenerationID int
    33  
    34  	// ID of the group member submitting the offsets.
    35  	MemberID string
    36  
    37  	// GroupInstanceID is a unique identifier for the consumer.
    38  	GroupInstanceID string
    39  
    40  	// Set of topic partitions to publish the offsets for.
    41  	//
    42  	// Not that offset commits need to be submitted to the broker acting as the
    43  	// group coordinator. This will be automatically resolved by the transport.
    44  	Topics map[string][]TxnOffsetCommit
    45  }
    46  
    47  // TxnOffsetCommit represent the commit of an offset to a partition within a transaction.
    48  //
    49  // The extra metadata is opaque to the kafka protocol, it is intended to hold
    50  // information like an identifier for the process that committed the offset,
    51  // or the time at which the commit was made.
    52  type TxnOffsetCommit struct {
    53  	Partition int
    54  	Offset    int64
    55  	Metadata  string
    56  }
    57  
    58  // TxnOffsetFetchResponse represents a response from a kafka broker to an offset
    59  // commit request within a transaction.
    60  type TxnOffsetCommitResponse struct {
    61  	// The amount of time that the broker throttled the request.
    62  	Throttle time.Duration
    63  
    64  	// Set of topic partitions that the kafka broker has accepted offset commits
    65  	// for.
    66  	Topics map[string][]TxnOffsetCommitPartition
    67  }
    68  
    69  // TxnOffsetFetchPartition represents the state of a single partition in responses
    70  // to committing offsets within a  transaction.
    71  type TxnOffsetCommitPartition struct {
    72  	// ID of the partition.
    73  	Partition int
    74  
    75  	// An error that may have occurred while attempting to publish consumer
    76  	// group offsets for this partition.
    77  	//
    78  	// The error contains both the kafka error code, and an error message
    79  	// returned by the kafka broker. Programs may use the standard errors.Is
    80  	// function to test the error against kafka error codes.
    81  	Error error
    82  }
    83  
    84  // TxnOffsetCommit sends an txn offset commit request to a kafka broker and returns the
    85  // response.
    86  func (c *Client) TxnOffsetCommit(
    87  	ctx context.Context,
    88  	req *TxnOffsetCommitRequest,
    89  ) (*TxnOffsetCommitResponse, error) {
    90  	protoReq := &txnoffsetcommit.Request{
    91  		TransactionalID: req.TransactionalID,
    92  		GroupID:         req.GroupID,
    93  		ProducerID:      int64(req.ProducerID),
    94  		ProducerEpoch:   int16(req.ProducerEpoch),
    95  		GenerationID:    int32(req.GenerationID),
    96  		MemberID:        req.MemberID,
    97  		GroupInstanceID: req.GroupInstanceID,
    98  		Topics:          make([]txnoffsetcommit.RequestTopic, 0, len(req.Topics)),
    99  	}
   100  
   101  	for topic, partitions := range req.Topics {
   102  		parts := make([]txnoffsetcommit.RequestPartition, len(partitions))
   103  		for i, partition := range partitions {
   104  			parts[i] = txnoffsetcommit.RequestPartition{
   105  				Partition:         int32(partition.Partition),
   106  				CommittedOffset:   int64(partition.Offset),
   107  				CommittedMetadata: partition.Metadata,
   108  			}
   109  		}
   110  		t := txnoffsetcommit.RequestTopic{
   111  			Name:       topic,
   112  			Partitions: parts,
   113  		}
   114  
   115  		protoReq.Topics = append(protoReq.Topics, t)
   116  	}
   117  
   118  	m, err := c.roundTrip(ctx, req.Addr, protoReq)
   119  	if err != nil {
   120  		return nil, fmt.Errorf("kafka.(*Client).TxnOffsetCommit: %w", err)
   121  	}
   122  
   123  	r := m.(*txnoffsetcommit.Response)
   124  
   125  	res := &TxnOffsetCommitResponse{
   126  		Throttle: makeDuration(r.ThrottleTimeMs),
   127  		Topics:   make(map[string][]TxnOffsetCommitPartition, len(r.Topics)),
   128  	}
   129  
   130  	for _, topic := range r.Topics {
   131  		partitions := make([]TxnOffsetCommitPartition, 0, len(topic.Partitions))
   132  		for _, partition := range topic.Partitions {
   133  			partitions = append(partitions, TxnOffsetCommitPartition{
   134  				Partition: int(partition.Partition),
   135  				Error:     makeError(partition.ErrorCode, ""),
   136  			})
   137  		}
   138  		res.Topics[topic.Name] = partitions
   139  	}
   140  
   141  	return res, nil
   142  }