github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/findcoordinator.go (about)

     1  package kafka
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"fmt"
     7  	"net"
     8  	"time"
     9  
    10  	"github.com/segmentio/kafka-go/protocol/findcoordinator"
    11  )
    12  
    13  // CoordinatorKeyType is used to specify the type of coordinator to look for.
    14  type CoordinatorKeyType int8
    15  
    16  const (
    17  	// CoordinatorKeyTypeConsumer type is used when looking for a Group coordinator.
    18  	CoordinatorKeyTypeConsumer CoordinatorKeyType = 0
    19  
    20  	// CoordinatorKeyTypeTransaction type is used when looking for a Transaction coordinator.
    21  	CoordinatorKeyTypeTransaction CoordinatorKeyType = 1
    22  )
    23  
    24  // FindCoordinatorRequest is the request structure for the FindCoordinator function.
    25  type FindCoordinatorRequest struct {
    26  	// Address of the kafka broker to send the request to.
    27  	Addr net.Addr
    28  
    29  	// The coordinator key.
    30  	Key string
    31  
    32  	// The coordinator key type. (Group, transaction, etc.)
    33  	KeyType CoordinatorKeyType
    34  }
    35  
    36  // FindCoordinatorResponseCoordinator contains details about the found coordinator.
    37  type FindCoordinatorResponseCoordinator struct {
    38  	// NodeID holds the broker id.
    39  	NodeID int
    40  
    41  	// Host of the broker
    42  	Host string
    43  
    44  	// Port on which broker accepts requests
    45  	Port int
    46  }
    47  
    48  // FindCoordinatorResponse is the response structure for the FindCoordinator function.
    49  type FindCoordinatorResponse struct {
    50  	// The Transaction/Group Coordinator details
    51  	Coordinator *FindCoordinatorResponseCoordinator
    52  
    53  	// The amount of time that the broker throttled the request.
    54  	Throttle time.Duration
    55  
    56  	// An error that may have occurred while attempting to retrieve Coordinator
    57  	//
    58  	// The error contains both the kafka error code, and an error message
    59  	// returned by the kafka broker.
    60  	Error error
    61  }
    62  
    63  // FindCoordinator sends a findCoordinator request to a kafka broker and returns the
    64  // response.
    65  func (c *Client) FindCoordinator(ctx context.Context, req *FindCoordinatorRequest) (*FindCoordinatorResponse, error) {
    66  
    67  	m, err := c.roundTrip(ctx, req.Addr, &findcoordinator.Request{
    68  		Key:     req.Key,
    69  		KeyType: int8(req.KeyType),
    70  	})
    71  
    72  	if err != nil {
    73  		return nil, fmt.Errorf("kafka.(*Client).FindCoordinator: %w", err)
    74  	}
    75  
    76  	res := m.(*findcoordinator.Response)
    77  	coordinator := &FindCoordinatorResponseCoordinator{
    78  		NodeID: int(res.NodeID),
    79  		Host:   res.Host,
    80  		Port:   int(res.Port),
    81  	}
    82  	ret := &FindCoordinatorResponse{
    83  		Throttle:    makeDuration(res.ThrottleTimeMs),
    84  		Error:       makeError(res.ErrorCode, res.ErrorMessage),
    85  		Coordinator: coordinator,
    86  	}
    87  
    88  	return ret, nil
    89  }
    90  
    91  // FindCoordinatorRequestV0 requests the coordinator for the specified group or transaction
    92  //
    93  // See http://kafka.apache.org/protocol.html#The_Messages_FindCoordinator
    94  type findCoordinatorRequestV0 struct {
    95  	// CoordinatorKey holds id to use for finding the coordinator (for groups, this is
    96  	// the groupId, for transactional producers, this is the transactional id)
    97  	CoordinatorKey string
    98  }
    99  
   100  func (t findCoordinatorRequestV0) size() int32 {
   101  	return sizeofString(t.CoordinatorKey)
   102  }
   103  
   104  func (t findCoordinatorRequestV0) writeTo(wb *writeBuffer) {
   105  	wb.writeString(t.CoordinatorKey)
   106  }
   107  
   108  type findCoordinatorResponseCoordinatorV0 struct {
   109  	// NodeID holds the broker id.
   110  	NodeID int32
   111  
   112  	// Host of the broker
   113  	Host string
   114  
   115  	// Port on which broker accepts requests
   116  	Port int32
   117  }
   118  
   119  func (t findCoordinatorResponseCoordinatorV0) size() int32 {
   120  	return sizeofInt32(t.NodeID) +
   121  		sizeofString(t.Host) +
   122  		sizeofInt32(t.Port)
   123  }
   124  
   125  func (t findCoordinatorResponseCoordinatorV0) writeTo(wb *writeBuffer) {
   126  	wb.writeInt32(t.NodeID)
   127  	wb.writeString(t.Host)
   128  	wb.writeInt32(t.Port)
   129  }
   130  
   131  func (t *findCoordinatorResponseCoordinatorV0) readFrom(r *bufio.Reader, size int) (remain int, err error) {
   132  	if remain, err = readInt32(r, size, &t.NodeID); err != nil {
   133  		return
   134  	}
   135  	if remain, err = readString(r, remain, &t.Host); err != nil {
   136  		return
   137  	}
   138  	if remain, err = readInt32(r, remain, &t.Port); err != nil {
   139  		return
   140  	}
   141  	return
   142  }
   143  
   144  type findCoordinatorResponseV0 struct {
   145  	// ErrorCode holds response error code
   146  	ErrorCode int16
   147  
   148  	// Coordinator holds host and port information for the coordinator
   149  	Coordinator findCoordinatorResponseCoordinatorV0
   150  }
   151  
   152  func (t findCoordinatorResponseV0) size() int32 {
   153  	return sizeofInt16(t.ErrorCode) +
   154  		t.Coordinator.size()
   155  }
   156  
   157  func (t findCoordinatorResponseV0) writeTo(wb *writeBuffer) {
   158  	wb.writeInt16(t.ErrorCode)
   159  	t.Coordinator.writeTo(wb)
   160  }
   161  
   162  func (t *findCoordinatorResponseV0) readFrom(r *bufio.Reader, size int) (remain int, err error) {
   163  	if remain, err = readInt16(r, size, &t.ErrorCode); err != nil {
   164  		return
   165  	}
   166  	if remain, err = (&t.Coordinator).readFrom(r, remain); err != nil {
   167  		return
   168  	}
   169  	return
   170  }