github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/client/mq/kafka/producer/producer_option.go (about)

     1  package producer
     2  
     3  import (
     4  	"regexp"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/weedge/lib/client/mq/kafka/auth"
     9  )
    10  
    11  type ProducerOptions struct {
    12  	version           string        // kafka version
    13  	clientID          string        // The client ID sent with every request to the brokers.
    14  	brokerList        []string      // broker list
    15  	partitioning      string        // key {partition}(manual),hash,random
    16  	requiredAcks      int           // required ack
    17  	timeOut           time.Duration // The duration the producer will wait to receive -required-acks
    18  	retryMaxCn        int           // retry max cn (default: 3)
    19  	compression       string        // msg compression(gzip,snappy,lz4,zstd)
    20  	maxOpenRequests   int           // The maximum number of unacknowledged requests the client will send on a single connection before blocking (default: 5)
    21  	maxMessageBytes   int           // The max permitted size of a message (default: 1000000)
    22  	channelBufferSize int           // The number of events to buffer in internal and external channels.
    23  
    24  	// flush batches
    25  	flushFrequencyMs int // The best-effort frequency of flushes
    26  	flushBytes       int // The best-effort number of bytes needed to trigger a flush.
    27  	flushMessages    int // The best-effort number of messages needed to trigger a flush.
    28  	flushMaxMessages int // The maximum number of messages the producer will send in a single request.
    29  
    30  	*auth.AuthOptions
    31  }
    32  
    33  type Option interface {
    34  	apply(o *ProducerOptions)
    35  }
    36  
    37  type funcServerOption struct {
    38  	f func(o *ProducerOptions)
    39  }
    40  
    41  func (fdo *funcServerOption) apply(o *ProducerOptions) {
    42  	fdo.f(o)
    43  }
    44  
    45  func newFuncServerOption(f func(o *ProducerOptions)) *funcServerOption {
    46  	return &funcServerOption{
    47  		f: f,
    48  	}
    49  }
    50  
    51  // kafka version support kafka min version 0.8.2.0
    52  func WithVersion(version string) Option {
    53  	return newFuncServerOption(func(o *ProducerOptions) {
    54  		if len(version) == 0 {
    55  			version = "0.8.2.0"
    56  		}
    57  		o.version = version
    58  	})
    59  }
    60  
    61  // The client ID sent with every request to the brokers.
    62  func WithClientID(clientId string) Option {
    63  	return newFuncServerOption(func(o *ProducerOptions) {
    64  		o.clientID = clientId
    65  	})
    66  }
    67  
    68  // The duration the producer will wait to receive -required-acks
    69  func WithTimeOut(timeOut time.Duration) Option {
    70  	return newFuncServerOption(func(o *ProducerOptions) {
    71  		o.timeOut = timeOut
    72  	})
    73  }
    74  
    75  func WithChannelBufferSize(channelBufferSize int) Option {
    76  	return newFuncServerOption(func(o *ProducerOptions) {
    77  		o.channelBufferSize = channelBufferSize
    78  	})
    79  }
    80  
    81  func WithMaxOpenRequests(maxOpenRequests int) Option {
    82  	return newFuncServerOption(func(o *ProducerOptions) {
    83  		o.maxOpenRequests = maxOpenRequests
    84  	})
    85  }
    86  
    87  func WithMaxMessageBytes(maxMessageBytes int) Option {
    88  	return newFuncServerOption(func(o *ProducerOptions) {
    89  		o.maxMessageBytes = maxMessageBytes
    90  	})
    91  }
    92  
    93  // kafka brokers ip:port,ip:port
    94  func WithBrokerList(brokers string) Option {
    95  	return newFuncServerOption(func(o *ProducerOptions) {
    96  		if len(brokers) == 0 {
    97  			panic("empty brokers")
    98  		}
    99  		o.brokerList = strings.Split(brokers, ",")
   100  	})
   101  }
   102  
   103  // key partition: partition(manual),hash,random
   104  // - manual partitioning if a partition number is provided
   105  // - hash partitioning by msg key
   106  // - random partitioning otherwise.
   107  func WithPartitioning(partitioning string) Option {
   108  	return newFuncServerOption(func(o *ProducerOptions) {
   109  		o.partitioning = "hash"
   110  		match, _ := regexp.MatchString(`^[0-9]+$|^hash$|^random$|^roundrobin$`, partitioning)
   111  		if match {
   112  			o.partitioning = partitioning
   113  		}
   114  	})
   115  }
   116  
   117  // RequiredAcks is used in Produce Requests to tell the broker how many replica acknowledgements
   118  // it must see before responding. Any of the constants defined here are valid. On broker versions
   119  // prior to 0.8.2.0 any other positive int16 is also valid (the broker will wait for that many
   120  // acknowledgements) but in 0.8.2.0 and later this will raise an exception (it has been replaced
   121  // by setting the `min.isr` value in the brokers configuration).
   122  // 0: NoResponse doesn't send any response, the TCP ACK is all you get.
   123  // 1: WaitForLocal waits for only the local commit to succeed before responding.
   124  // -1: WaitForAll waits for all in-sync replicas to commit before responding.
   125  // The minimum number of in-sync replicas is configured on the broker via
   126  // the `min.insync.replicas` configuration key.
   127  func WithRequiredAcks(requiredAcks int) Option {
   128  	return newFuncServerOption(func(o *ProducerOptions) {
   129  		if requiredAcks < -1 {
   130  			requiredAcks = -1
   131  		}
   132  		if requiredAcks > 1 {
   133  			requiredAcks = 1
   134  		}
   135  		o.requiredAcks = requiredAcks
   136  	})
   137  }
   138  
   139  func WithRetryMaxCn(retryMaxCn int) Option {
   140  	return newFuncServerOption(func(o *ProducerOptions) {
   141  		if retryMaxCn <= 0 {
   142  			retryMaxCn = 3
   143  		}
   144  		o.retryMaxCn = retryMaxCn
   145  	})
   146  }
   147  
   148  func WithCompression(compression string) Option {
   149  	return newFuncServerOption(func(o *ProducerOptions) {
   150  		if _, ok := compressions[compression]; !ok {
   151  			panic("un support this compression" + compression)
   152  		}
   153  		o.compression = compression
   154  	})
   155  }
   156  
   157  func WithFlushFrequencyMs(flushFrequencyMs int) Option {
   158  	return newFuncServerOption(func(o *ProducerOptions) {
   159  		if flushFrequencyMs < 0 {
   160  			flushFrequencyMs = 0
   161  		}
   162  
   163  		o.flushFrequencyMs = flushFrequencyMs
   164  	})
   165  }
   166  
   167  func WithFlushBytes(flushBytes int) Option {
   168  	return newFuncServerOption(func(o *ProducerOptions) {
   169  		if flushBytes < 0 {
   170  			flushBytes = 0
   171  		}
   172  
   173  		o.flushBytes = flushBytes
   174  	})
   175  }
   176  
   177  func WithFlushMessages(flushMessages int) Option {
   178  	return newFuncServerOption(func(o *ProducerOptions) {
   179  		if flushMessages < 0 {
   180  			flushMessages = 0
   181  		}
   182  
   183  		o.flushMessages = flushMessages
   184  	})
   185  }
   186  
   187  func WithFlushMaxMessages(flushMaxMessages int) Option {
   188  	return newFuncServerOption(func(o *ProducerOptions) {
   189  		if flushMaxMessages < 0 {
   190  			flushMaxMessages = 0
   191  		}
   192  
   193  		o.flushMaxMessages = flushMaxMessages
   194  	})
   195  }
   196  
   197  func getProducerOptions(authOpts []auth.Option, opts ...Option) *ProducerOptions {
   198  	producerOptions := &ProducerOptions{
   199  		version:           "0.8.2.0",
   200  		clientID:          "",
   201  		brokerList:        nil,
   202  		partitioning:      "",
   203  		requiredAcks:      -1,
   204  		timeOut:           5 * time.Second,
   205  		retryMaxCn:        3,
   206  		compression:       "",
   207  		maxOpenRequests:   5,
   208  		maxMessageBytes:   1000000,
   209  		channelBufferSize: 256,
   210  		flushFrequencyMs:  0,
   211  		flushBytes:        0,
   212  		flushMessages:     0,
   213  		flushMaxMessages:  0,
   214  		AuthOptions:       auth.GetAuthOptions(authOpts...),
   215  	}
   216  
   217  	for _, o := range opts {
   218  		o.apply(producerOptions)
   219  	}
   220  
   221  	return producerOptions
   222  }