github.com/m3db/m3@v1.5.0/src/msg/producer/writer/options.go (about) 1 // Copyright (c) 2018 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package writer 22 23 import ( 24 "context" 25 "net" 26 "time" 27 28 "github.com/m3db/m3/src/cluster/placement" 29 "github.com/m3db/m3/src/cluster/services" 30 "github.com/m3db/m3/src/msg/protocol/proto" 31 "github.com/m3db/m3/src/msg/topic" 32 "github.com/m3db/m3/src/x/instrument" 33 "github.com/m3db/m3/src/x/pool" 34 "github.com/m3db/m3/src/x/retry" 35 ) 36 37 const ( 38 defaultPlacementWatchInitTimeout = 2 * time.Second 39 defaultTopicWatchInitTimeout = 2 * time.Second 40 defaultCloseCheckInterval = time.Second 41 defaultMessageQueueNewWritesScanInterval = 200 * time.Millisecond 42 defaultMessageQueueFullScanInterval = 5 * time.Second 43 defaultMessageQueueScanBatchSize = 16 44 defaultInitialAckMapSize = 1024 45 46 defaultNumConnections = 4 47 defaultConnectionDialTimeout = 5 * time.Second 48 defaultConnectionWriteTimeout = 5 * time.Second 49 defaultConnectionKeepAlivePeriod = 5 * time.Second 50 defaultConnectionResetDelay = 2 * time.Second 51 defaultConnectionFlushInterval = time.Second 52 // Using 65k which provides much better performance comparing 53 // to lower values like 1k ~ 8k. 54 defaultConnectionBufferSize = 2 << 15 // ~65kb 55 56 defaultWriterRetryInitialBackoff = time.Second * 5 57 ) 58 59 // ContextDialerFn allows customization of how a m3msg Writer connects to producer endpoints. 60 // See ConnectionOptions#ContextDialer 61 type ContextDialerFn func(ctx context.Context, network string, address string) (net.Conn, error) 62 63 // ConnectionOptions configs the connections. 64 type ConnectionOptions interface { 65 // NumConnections returns the number of connections. 66 NumConnections() int 67 68 // SetNumConnections sets the number of connections. 69 SetNumConnections(value int) ConnectionOptions 70 71 // ContextDialer allows customizing the way a m3msg Writer connects to producer endpoints. By default, this is: 72 // (&net.ContextDialer{}).DialContext. This can be used to do a variety of things, such as forwarding a connection 73 // over a proxy. 74 // NOTE: if your ContextDialerFn returns anything other a *net.TCPConn, TCP options such as KeepAlivePeriod 75 // will *not* be applied automatically. It is your responsibility to make sure these get applied as needed in 76 // your custom ContextDialerFn. 77 ContextDialer() ContextDialerFn 78 79 // SetContextDialer see ContextDialer. 80 SetContextDialer(fn ContextDialerFn) ConnectionOptions 81 82 // DialTimeout returns the dial timeout. 83 DialTimeout() time.Duration 84 85 // SetDialTimeout sets the dial timeout. 86 SetDialTimeout(value time.Duration) ConnectionOptions 87 88 // WriteTimeout returns the write timeout. 89 WriteTimeout() time.Duration 90 91 // SetWriteTimeout sets the write timeout. 92 SetWriteTimeout(value time.Duration) ConnectionOptions 93 94 // KeepAlivePeriod returns the keepAlivePeriod. 95 KeepAlivePeriod() time.Duration 96 97 // SetKeepAlivePeriod sets the keepAlivePeriod. 98 SetKeepAlivePeriod(value time.Duration) ConnectionOptions 99 100 // ResetDelay returns the delay before resetting connection. 101 ResetDelay() time.Duration 102 103 // SetResetDelay sets the delay before resetting connection. 104 SetResetDelay(value time.Duration) ConnectionOptions 105 106 // RetryOptions returns the options for connection retrier. 107 RetryOptions() retry.Options 108 109 // SetRetryOptions sets the options for connection retrier. 110 SetRetryOptions(value retry.Options) ConnectionOptions 111 112 // FlushInterval returns the interval for flushing the buffered bytes. 113 FlushInterval() time.Duration 114 115 // SetFlushInterval sets the interval for flushing the buffered bytes. 116 SetFlushInterval(value time.Duration) ConnectionOptions 117 118 // WriteBufferSize returns the buffer size for write. 119 WriteBufferSize() int 120 121 // SetWriteBufferSize sets the buffer size for write. 122 SetWriteBufferSize(value int) ConnectionOptions 123 124 // ReadBufferSize returns the buffer size for read. 125 ReadBufferSize() int 126 127 // SetReadBufferSize sets the buffer size for read. 128 SetReadBufferSize(value int) ConnectionOptions 129 130 // InstrumentOptions returns the instrument options. 131 InstrumentOptions() instrument.Options 132 133 // SetInstrumentOptions sets the instrument options. 134 SetInstrumentOptions(value instrument.Options) ConnectionOptions 135 } 136 137 type connectionOptions struct { 138 numConnections int 139 dialTimeout time.Duration 140 writeTimeout time.Duration 141 keepAlivePeriod time.Duration 142 resetDelay time.Duration 143 rOpts retry.Options 144 flushInterval time.Duration 145 writeBufferSize int 146 readBufferSize int 147 iOpts instrument.Options 148 dialer ContextDialerFn 149 } 150 151 // NewConnectionOptions creates ConnectionOptions. 152 func NewConnectionOptions() ConnectionOptions { 153 return &connectionOptions{ 154 numConnections: defaultNumConnections, 155 dialTimeout: defaultConnectionDialTimeout, 156 writeTimeout: defaultConnectionWriteTimeout, 157 keepAlivePeriod: defaultConnectionKeepAlivePeriod, 158 resetDelay: defaultConnectionResetDelay, 159 rOpts: retry.NewOptions(), 160 flushInterval: defaultConnectionFlushInterval, 161 writeBufferSize: defaultConnectionBufferSize, 162 readBufferSize: defaultConnectionBufferSize, 163 iOpts: instrument.NewOptions(), 164 dialer: nil, // Will default to net.Dialer{}.DialContext 165 } 166 } 167 168 func (opts *connectionOptions) NumConnections() int { 169 return opts.numConnections 170 } 171 172 func (opts *connectionOptions) SetNumConnections(value int) ConnectionOptions { 173 o := *opts 174 o.numConnections = value 175 return &o 176 } 177 178 func (opts *connectionOptions) DialTimeout() time.Duration { 179 return opts.dialTimeout 180 } 181 182 func (opts *connectionOptions) SetDialTimeout(value time.Duration) ConnectionOptions { 183 o := *opts 184 o.dialTimeout = value 185 return &o 186 } 187 188 func (opts *connectionOptions) ContextDialer() ContextDialerFn { 189 return opts.dialer 190 } 191 192 func (opts *connectionOptions) SetContextDialer(fn ContextDialerFn) ConnectionOptions { 193 o := *opts 194 o.dialer = fn 195 return &o 196 } 197 198 func (opts *connectionOptions) WriteTimeout() time.Duration { 199 return opts.writeTimeout 200 } 201 202 func (opts *connectionOptions) SetWriteTimeout(value time.Duration) ConnectionOptions { 203 o := *opts 204 o.writeTimeout = value 205 return &o 206 } 207 208 func (opts *connectionOptions) KeepAlivePeriod() time.Duration { 209 return opts.keepAlivePeriod 210 } 211 212 func (opts *connectionOptions) SetKeepAlivePeriod(value time.Duration) ConnectionOptions { 213 o := *opts 214 o.keepAlivePeriod = value 215 return &o 216 } 217 218 func (opts *connectionOptions) RetryOptions() retry.Options { 219 return opts.rOpts 220 } 221 222 func (opts *connectionOptions) SetRetryOptions(value retry.Options) ConnectionOptions { 223 o := *opts 224 o.rOpts = value 225 return &o 226 } 227 228 func (opts *connectionOptions) ResetDelay() time.Duration { 229 return opts.resetDelay 230 } 231 232 func (opts *connectionOptions) SetResetDelay(value time.Duration) ConnectionOptions { 233 o := *opts 234 o.resetDelay = value 235 return &o 236 } 237 238 func (opts *connectionOptions) FlushInterval() time.Duration { 239 return opts.flushInterval 240 } 241 242 func (opts *connectionOptions) SetFlushInterval(value time.Duration) ConnectionOptions { 243 o := *opts 244 o.flushInterval = value 245 return &o 246 } 247 248 func (opts *connectionOptions) WriteBufferSize() int { 249 return opts.writeBufferSize 250 } 251 252 func (opts *connectionOptions) SetWriteBufferSize(value int) ConnectionOptions { 253 o := *opts 254 o.writeBufferSize = value 255 return &o 256 } 257 258 func (opts *connectionOptions) ReadBufferSize() int { 259 return opts.readBufferSize 260 } 261 262 func (opts *connectionOptions) SetReadBufferSize(value int) ConnectionOptions { 263 o := *opts 264 o.readBufferSize = value 265 return &o 266 } 267 268 func (opts *connectionOptions) InstrumentOptions() instrument.Options { 269 return opts.iOpts 270 } 271 272 func (opts *connectionOptions) SetInstrumentOptions(value instrument.Options) ConnectionOptions { 273 o := *opts 274 o.iOpts = value 275 return &o 276 } 277 278 // Options configs the writer. 279 type Options interface { 280 // TopicName returns the topic name. 281 TopicName() string 282 283 // SetTopicName sets the topic name. 284 SetTopicName(value string) Options 285 286 // TopicService returns the topic service. 287 TopicService() topic.Service 288 289 // SetTopicService sets the topic service. 290 SetTopicService(value topic.Service) Options 291 292 // TopicWatchInitTimeout returns the timeout for topic watch initialization. 293 TopicWatchInitTimeout() time.Duration 294 295 // SetTopicWatchInitTimeout sets the timeout for topic watch initialization. 296 SetTopicWatchInitTimeout(value time.Duration) Options 297 298 // ServiceDiscovery returns the client to service discovery service. 299 ServiceDiscovery() services.Services 300 301 // SetServiceDiscovery sets the client to service discovery services. 302 SetServiceDiscovery(value services.Services) Options 303 304 // PlacementOptions returns the placement options. 305 PlacementOptions() placement.Options 306 307 // SetPlacementOptions sets the placement options. 308 SetPlacementOptions(value placement.Options) Options 309 310 // PlacementWatchInitTimeout returns the timeout for placement watch initialization. 311 PlacementWatchInitTimeout() time.Duration 312 313 // SetPlacementWatchInitTimeout sets the timeout for placement watch initialization. 314 SetPlacementWatchInitTimeout(value time.Duration) Options 315 316 // MessagePoolOptions returns the options of pool for messages. 317 MessagePoolOptions() pool.ObjectPoolOptions 318 319 // SetMessagePoolOptions sets the options of pool for messages. 320 SetMessagePoolOptions(value pool.ObjectPoolOptions) Options 321 322 // MessageRetryNanosFn returns the MessageRetryNanosFn. 323 MessageRetryNanosFn() MessageRetryNanosFn 324 325 // SetMessageRetryNanosFn sets the MessageRetryNanosFn. 326 SetMessageRetryNanosFn(value MessageRetryNanosFn) Options 327 328 // MessageQueueNewWritesScanInterval returns the interval between scanning 329 // message queue for new writes. 330 MessageQueueNewWritesScanInterval() time.Duration 331 332 // SetMessageQueueNewWritesScanInterval sets the interval between scanning 333 // message queue for new writes. 334 SetMessageQueueNewWritesScanInterval(value time.Duration) Options 335 336 // MessageQueueFullScanInterval returns the interval between scanning 337 // message queue for retriable writes and cleanups. 338 MessageQueueFullScanInterval() time.Duration 339 340 // SetMessageQueueFullScanInterval sets the interval between scanning 341 // message queue for retriable writes and cleanups. 342 SetMessageQueueFullScanInterval(value time.Duration) Options 343 344 // MessageQueueScanBatchSize returns the batch size for queue scan. 345 MessageQueueScanBatchSize() int 346 347 // SetMessageQueueScanBatchSize sets the batch size for queue scan. 348 SetMessageQueueScanBatchSize(value int) Options 349 350 // InitialAckMapSize returns the initial size of the ack map. 351 InitialAckMapSize() int 352 353 // SetInitialAckMapSize sets the initial size of the ack map. 354 SetInitialAckMapSize(value int) Options 355 356 // CloseCheckInterval returns the close check interval. 357 CloseCheckInterval() time.Duration 358 359 // SetCloseCheckInterval sets the close check interval. 360 SetCloseCheckInterval(value time.Duration) Options 361 362 // AckErrorRetryOptions returns the retrier for ack errors. 363 AckErrorRetryOptions() retry.Options 364 365 // SetAckErrorRetryOptions sets the retrier for ack errors. 366 SetAckErrorRetryOptions(value retry.Options) Options 367 368 // EncoderOptions returns the encoder's options. 369 EncoderOptions() proto.Options 370 371 // SetEncoderOptions sets the encoder's options. 372 SetEncoderOptions(value proto.Options) Options 373 374 // DecoderOptions returns the decoder's options. 375 DecoderOptions() proto.Options 376 377 // SetDecoderOptions sets the decoder's options. 378 SetDecoderOptions(value proto.Options) Options 379 380 // ConnectionOptions returns the options for connections. 381 ConnectionOptions() ConnectionOptions 382 383 // SetConnectionOptions sets the options for connections. 384 SetConnectionOptions(value ConnectionOptions) Options 385 386 // InstrumentOptions returns the instrument options. 387 InstrumentOptions() instrument.Options 388 389 // SetInstrumentOptions sets the instrument options. 390 SetInstrumentOptions(value instrument.Options) Options 391 392 // IgnoreCutoffCutover returns a flag indicating whether cutoff/cutover timestamps are ignored. 393 IgnoreCutoffCutover() bool 394 395 // SetIgnoreCutoffCutover sets a flag controlling whether cutoff/cutover timestamps are ignored. 396 SetIgnoreCutoffCutover(value bool) Options 397 398 // WithoutConsumerScope disables the consumer scope for metrics. For large m3msg deployments the consumer 399 // scope can add a lot of cardinality to the metrics. 400 WithoutConsumerScope() bool 401 402 // SetWithoutConsumerScope sets the value for WithoutConsumerScope. 403 SetWithoutConsumerScope(value bool) Options 404 } 405 406 type writerOptions struct { 407 topicName string 408 topicService topic.Service 409 topicWatchInitTimeout time.Duration 410 services services.Services 411 placementOpts placement.Options 412 placementWatchInitTimeout time.Duration 413 messageRetryNanosFn MessageRetryNanosFn 414 messagePoolOptions pool.ObjectPoolOptions 415 messageQueueNewWritesScanInterval time.Duration 416 messageQueueFullScanInterval time.Duration 417 messageQueueScanBatchSize int 418 initialAckMapSize int 419 closeCheckInterval time.Duration 420 ackErrRetryOpts retry.Options 421 encOpts proto.Options 422 decOpts proto.Options 423 cOpts ConnectionOptions 424 iOpts instrument.Options 425 ignoreCutoffCutover bool 426 withoutConsumerScope bool 427 } 428 429 // NewOptions creates Options. 430 func NewOptions() Options { 431 messageRetryOpts := retry.NewOptions(). 432 SetInitialBackoff(defaultWriterRetryInitialBackoff) 433 return &writerOptions{ 434 topicWatchInitTimeout: defaultTopicWatchInitTimeout, 435 placementOpts: placement.NewOptions(), 436 placementWatchInitTimeout: defaultPlacementWatchInitTimeout, 437 messageRetryNanosFn: NextRetryNanosFn(messageRetryOpts), 438 messageQueueNewWritesScanInterval: defaultMessageQueueNewWritesScanInterval, 439 messageQueueFullScanInterval: defaultMessageQueueFullScanInterval, 440 messageQueueScanBatchSize: defaultMessageQueueScanBatchSize, 441 initialAckMapSize: defaultInitialAckMapSize, 442 closeCheckInterval: defaultCloseCheckInterval, 443 ackErrRetryOpts: retry.NewOptions(), 444 encOpts: proto.NewOptions(), 445 decOpts: proto.NewOptions(), 446 cOpts: NewConnectionOptions(), 447 iOpts: instrument.NewOptions(), 448 } 449 } 450 451 func (opts *writerOptions) TopicName() string { 452 return opts.topicName 453 } 454 455 func (opts *writerOptions) SetTopicName(value string) Options { 456 o := *opts 457 o.topicName = value 458 return &o 459 } 460 461 func (opts *writerOptions) TopicService() topic.Service { 462 return opts.topicService 463 } 464 465 func (opts *writerOptions) SetTopicService(value topic.Service) Options { 466 o := *opts 467 o.topicService = value 468 return &o 469 } 470 471 func (opts *writerOptions) TopicWatchInitTimeout() time.Duration { 472 return opts.topicWatchInitTimeout 473 } 474 475 func (opts *writerOptions) SetTopicWatchInitTimeout(value time.Duration) Options { 476 o := *opts 477 o.topicWatchInitTimeout = value 478 return &o 479 } 480 481 func (opts *writerOptions) ServiceDiscovery() services.Services { 482 return opts.services 483 } 484 485 func (opts *writerOptions) SetServiceDiscovery(value services.Services) Options { 486 o := *opts 487 o.services = value 488 return &o 489 } 490 491 func (opts *writerOptions) PlacementOptions() placement.Options { 492 return opts.placementOpts 493 } 494 495 func (opts *writerOptions) SetPlacementOptions(value placement.Options) Options { 496 o := *opts 497 o.placementOpts = value 498 return &o 499 } 500 501 func (opts *writerOptions) PlacementWatchInitTimeout() time.Duration { 502 return opts.placementWatchInitTimeout 503 } 504 505 func (opts *writerOptions) SetPlacementWatchInitTimeout(value time.Duration) Options { 506 o := *opts 507 o.placementWatchInitTimeout = value 508 return &o 509 } 510 511 func (opts *writerOptions) MessagePoolOptions() pool.ObjectPoolOptions { 512 return opts.messagePoolOptions 513 } 514 515 func (opts *writerOptions) SetMessagePoolOptions(value pool.ObjectPoolOptions) Options { 516 o := *opts 517 o.messagePoolOptions = value 518 return &o 519 } 520 521 func (opts *writerOptions) MessageRetryNanosFn() MessageRetryNanosFn { 522 return opts.messageRetryNanosFn 523 } 524 525 func (opts *writerOptions) SetMessageRetryNanosFn(value MessageRetryNanosFn) Options { 526 o := *opts 527 o.messageRetryNanosFn = value 528 return &o 529 } 530 531 func (opts *writerOptions) MessageQueueNewWritesScanInterval() time.Duration { 532 return opts.messageQueueNewWritesScanInterval 533 } 534 535 func (opts *writerOptions) SetMessageQueueNewWritesScanInterval(value time.Duration) Options { 536 o := *opts 537 o.messageQueueNewWritesScanInterval = value 538 return &o 539 } 540 541 func (opts *writerOptions) MessageQueueFullScanInterval() time.Duration { 542 return opts.messageQueueFullScanInterval 543 } 544 545 func (opts *writerOptions) SetMessageQueueFullScanInterval(value time.Duration) Options { 546 o := *opts 547 o.messageQueueFullScanInterval = value 548 return &o 549 } 550 551 func (opts *writerOptions) MessageQueueScanBatchSize() int { 552 return opts.messageQueueScanBatchSize 553 } 554 555 func (opts *writerOptions) SetMessageQueueScanBatchSize(value int) Options { 556 o := *opts 557 o.messageQueueScanBatchSize = value 558 return &o 559 } 560 561 func (opts *writerOptions) InitialAckMapSize() int { 562 return opts.initialAckMapSize 563 } 564 565 func (opts *writerOptions) SetInitialAckMapSize(value int) Options { 566 o := *opts 567 o.initialAckMapSize = value 568 return &o 569 } 570 571 func (opts *writerOptions) CloseCheckInterval() time.Duration { 572 return opts.closeCheckInterval 573 } 574 575 func (opts *writerOptions) SetCloseCheckInterval(value time.Duration) Options { 576 o := *opts 577 o.closeCheckInterval = value 578 return &o 579 } 580 581 func (opts *writerOptions) AckErrorRetryOptions() retry.Options { 582 return opts.ackErrRetryOpts 583 } 584 585 func (opts *writerOptions) SetAckErrorRetryOptions(value retry.Options) Options { 586 o := *opts 587 o.ackErrRetryOpts = value 588 return &o 589 } 590 591 func (opts *writerOptions) EncoderOptions() proto.Options { 592 return opts.encOpts 593 } 594 595 func (opts *writerOptions) SetEncoderOptions(value proto.Options) Options { 596 o := *opts 597 o.encOpts = value 598 return &o 599 } 600 601 func (opts *writerOptions) DecoderOptions() proto.Options { 602 return opts.decOpts 603 } 604 605 func (opts *writerOptions) SetDecoderOptions(value proto.Options) Options { 606 o := *opts 607 o.decOpts = value 608 return &o 609 } 610 611 func (opts *writerOptions) ConnectionOptions() ConnectionOptions { 612 return opts.cOpts 613 } 614 615 func (opts *writerOptions) SetConnectionOptions(value ConnectionOptions) Options { 616 o := *opts 617 o.cOpts = value 618 return &o 619 } 620 621 func (opts *writerOptions) InstrumentOptions() instrument.Options { 622 return opts.iOpts 623 } 624 625 func (opts *writerOptions) SetInstrumentOptions(value instrument.Options) Options { 626 o := *opts 627 o.iOpts = value 628 return &o 629 } 630 631 func (opts *writerOptions) IgnoreCutoffCutover() bool { 632 return opts.ignoreCutoffCutover 633 } 634 635 func (opts *writerOptions) SetIgnoreCutoffCutover(value bool) Options { 636 o := *opts 637 o.ignoreCutoffCutover = value 638 return &o 639 } 640 641 func (opts *writerOptions) WithoutConsumerScope() bool { 642 return opts.withoutConsumerScope 643 } 644 645 func (opts *writerOptions) SetWithoutConsumerScope(value bool) Options { 646 o := *opts 647 o.withoutConsumerScope = value 648 return &o 649 }