package fanout import "time" const ( defaultPublishTimeout = time.Second minPublishTimeout = time.Millisecond * 100 defaultReceiverCallbackTimeout = time.Second minReceiverCallbackTimeout = time.Millisecond * 100 defaultAddSubscriberTimeout = time.Millisecond * 100 minAddSubscriberTimeout = time.Millisecond * 100 defaultReceiverBufferSize = 100 defaultMessageBufferSize = 1024 defaultSubscriberBufferSize = 100 ) type config struct { publishTimeout time.Duration receiverBufferSize int receiverCallbackTimeout time.Duration publishBufferSize int subscriberBufferSize int addSubscriberTimeout time.Duration } // Option configures a FanOut type Option func(*config) // WithPublishTimeout sets the internal timeout for publishing messages to the fanout func WithPublishTimeout(timeout time.Duration) Option { if timeout < defaultPublishTimeout { timeout = defaultPublishTimeout } return func(c *config) { c.publishTimeout = timeout } } // WithReceiverBufferSize sets the buffer size for the buffer between fanout and subscriber receiver func WithReceiverBufferSize(size int) Option { if size < 1 { size = 1 } return func(c *config) { c.receiverBufferSize = size } } // WithReceiverCallbackTimeout sets the timeout for the callback function of the receiver func WithReceiverCallbackTimeout(timeout time.Duration) Option { if timeout < minReceiverCallbackTimeout { timeout = minReceiverCallbackTimeout } return func(c *config) { c.receiverCallbackTimeout = timeout } } // WithMessagesBufferSize sets the buffer size for the buffer that holds messages to be published func WithMessagesBufferSize(size int) Option { if size < 1 { size = 1 } return func(c *config) { c.publishBufferSize = size } } // WithSubscriberBufferSize sets the new subscriber requsts buffer size func WithSubscriberBufferSize(size int) Option { if size < 1 { size = 1 } return func(c *config) { c.subscriberBufferSize = size } } // WithAddSubscriberTimeout sets the timeout for adding a subscriber // If it is not possible to add a subscriber within the timeout, // it means the fanout is at capacity, and it is better to reject the subscriber, // that will likely be propagated to the downstream, // which would retry and eventually succeed with another instance func WithAddSubscriberTimeout(timeout time.Duration) Option { if timeout < minAddSubscriberTimeout { timeout = minAddSubscriberTimeout } return func(c *config) { c.addSubscriberTimeout = timeout } } func defaultFanOutConfig() config { var c config c.apply( WithPublishTimeout(defaultPublishTimeout), WithMessagesBufferSize(defaultMessageBufferSize), WithReceiverCallbackTimeout(defaultReceiverCallbackTimeout), WithReceiverBufferSize(defaultReceiverBufferSize), WithSubscriberBufferSize(defaultSubscriberBufferSize), WithAddSubscriberTimeout(defaultAddSubscriberTimeout), ) return c } func (c *config) apply(opts ...Option) { for _, opt := range opts { opt(c) } }