Updated connection config naming to introduce a dedicated pool configuration.
This commit is contained in:
58
config.go
58
config.go
@@ -5,9 +5,19 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Types
|
||||||
|
|
||||||
type CloseHandler func(code int, text string) error
|
type CloseHandler func(code int, text string) error
|
||||||
|
|
||||||
type Config struct {
|
// Pool Config
|
||||||
|
|
||||||
|
type PoolConfig struct {
|
||||||
|
ConnectionConfig *ConnectionConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection Config
|
||||||
|
|
||||||
|
type ConnectionConfig struct {
|
||||||
CloseHandler CloseHandler
|
CloseHandler CloseHandler
|
||||||
WriteTimeout time.Duration
|
WriteTimeout time.Duration
|
||||||
Retry *RetryConfig
|
Retry *RetryConfig
|
||||||
@@ -20,21 +30,21 @@ type RetryConfig struct {
|
|||||||
JitterFactor float64
|
JitterFactor float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigOption func(*Config) error
|
type ConnectionOption func(*ConnectionConfig) error
|
||||||
|
|
||||||
func NewConfig(options ...ConfigOption) (*Config, error) {
|
func NewConnectionConfig(options ...ConnectionOption) (*ConnectionConfig, error) {
|
||||||
conf := GetDefaultConfig()
|
conf := GetDefaultConnectionConfig()
|
||||||
if err := SetConfig(conf, options...); err != nil {
|
if err := applyConnectionOptions(conf, options...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := ValidateConfig(conf); err != nil {
|
if err := validateConnectionConfig(conf); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDefaultConfig() *Config {
|
func GetDefaultConnectionConfig() *ConnectionConfig {
|
||||||
return &Config{
|
return &ConnectionConfig{
|
||||||
CloseHandler: nil,
|
CloseHandler: nil,
|
||||||
WriteTimeout: 30 * time.Second,
|
WriteTimeout: 30 * time.Second,
|
||||||
Retry: GetDefaultRetryConfig(),
|
Retry: GetDefaultRetryConfig(),
|
||||||
@@ -50,7 +60,7 @@ func GetDefaultRetryConfig() *RetryConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetConfig(config *Config, options ...ConfigOption) error {
|
func applyConnectionOptions(config *ConnectionConfig, options ...ConnectionOption) error {
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
if err := option(config); err != nil {
|
if err := option(config); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +69,7 @@ func SetConfig(config *Config, options ...ConfigOption) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateConfig(config *Config) error {
|
func validateConnectionConfig(config *ConnectionConfig) error {
|
||||||
if config.Retry != nil {
|
if config.Retry != nil {
|
||||||
if config.Retry.InitialDelay > config.Retry.MaxDelay {
|
if config.Retry.InitialDelay > config.Retry.MaxDelay {
|
||||||
return errors.NewConfigError("initial delay may not exceed maximum delay")
|
return errors.NewConfigError("initial delay may not exceed maximum delay")
|
||||||
@@ -71,16 +81,16 @@ func ValidateConfig(config *Config) error {
|
|||||||
|
|
||||||
// Configuration Options
|
// Configuration Options
|
||||||
|
|
||||||
func WithCloseHandler(handler CloseHandler) ConfigOption {
|
func WithCloseHandler(handler CloseHandler) ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
c.CloseHandler = handler
|
c.CloseHandler = handler
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When WriteTimeout is set to zero, read timeouts are disabled.
|
// When WriteTimeout is set to zero, read timeouts are disabled.
|
||||||
func WithWriteTimeout(value time.Duration) ConfigOption {
|
func WithWriteTimeout(value time.Duration) ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return errors.InvalidWriteTimeout
|
return errors.InvalidWriteTimeout
|
||||||
}
|
}
|
||||||
@@ -95,15 +105,15 @@ func WithWriteTimeout(value time.Duration) ConfigOption {
|
|||||||
// If passed after granular retry options (WithRetryMaxRetries, etc.),
|
// If passed after granular retry options (WithRetryMaxRetries, etc.),
|
||||||
// it will overwrite them. Use either WithRetry alone or the granular
|
// it will overwrite them. Use either WithRetry alone or the granular
|
||||||
// options; not both.
|
// options; not both.
|
||||||
func WithRetry() ConfigOption {
|
func WithRetry() ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
c.Retry = GetDefaultRetryConfig()
|
c.Retry = GetDefaultRetryConfig()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRetryMaxRetries(value int) ConfigOption {
|
func WithRetryMaxRetries(value int) ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
if c.Retry == nil {
|
if c.Retry == nil {
|
||||||
c.Retry = GetDefaultRetryConfig()
|
c.Retry = GetDefaultRetryConfig()
|
||||||
}
|
}
|
||||||
@@ -115,8 +125,8 @@ func WithRetryMaxRetries(value int) ConfigOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRetryInitialDelay(value time.Duration) ConfigOption {
|
func WithRetryInitialDelay(value time.Duration) ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
if c.Retry == nil {
|
if c.Retry == nil {
|
||||||
c.Retry = GetDefaultRetryConfig()
|
c.Retry = GetDefaultRetryConfig()
|
||||||
}
|
}
|
||||||
@@ -128,8 +138,8 @@ func WithRetryInitialDelay(value time.Duration) ConfigOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRetryMaxDelay(value time.Duration) ConfigOption {
|
func WithRetryMaxDelay(value time.Duration) ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
if c.Retry == nil {
|
if c.Retry == nil {
|
||||||
c.Retry = GetDefaultRetryConfig()
|
c.Retry = GetDefaultRetryConfig()
|
||||||
}
|
}
|
||||||
@@ -141,8 +151,8 @@ func WithRetryMaxDelay(value time.Duration) ConfigOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRetryJitterFactor(value float64) ConfigOption {
|
func WithRetryJitterFactor(value float64) ConnectionOption {
|
||||||
return func(c *Config) error {
|
return func(c *ConnectionConfig) error {
|
||||||
if c.Retry == nil {
|
if c.Retry == nil {
|
||||||
c.Retry = GetDefaultRetryConfig()
|
c.Retry = GetDefaultRetryConfig()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,29 +10,29 @@ import (
|
|||||||
// Config Tests
|
// Config Tests
|
||||||
|
|
||||||
func TestNewConfig(t *testing.T) {
|
func TestNewConfig(t *testing.T) {
|
||||||
conf, err := NewConfig()
|
conf, err := NewConnectionConfig()
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, conf, &Config{
|
assert.Equal(t, conf, &ConnectionConfig{
|
||||||
CloseHandler: nil,
|
CloseHandler: nil,
|
||||||
WriteTimeout: 30 * time.Second,
|
WriteTimeout: 30 * time.Second,
|
||||||
Retry: GetDefaultRetryConfig(),
|
Retry: GetDefaultRetryConfig(),
|
||||||
})
|
})
|
||||||
|
|
||||||
// errors propagate
|
// errors propagate
|
||||||
_, err = NewConfig(WithRetryMaxRetries(-1))
|
_, err = NewConnectionConfig(WithRetryMaxRetries(-1))
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
_, err = NewConfig(WithRetryInitialDelay(10), WithRetryMaxDelay(1))
|
_, err = NewConnectionConfig(WithRetryInitialDelay(10), WithRetryMaxDelay(1))
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default Config Tests
|
// Default Config Tests
|
||||||
|
|
||||||
func TestDefaultConfig(t *testing.T) {
|
func TestDefaultConfig(t *testing.T) {
|
||||||
conf := GetDefaultConfig()
|
conf := GetDefaultConnectionConfig()
|
||||||
|
|
||||||
assert.Equal(t, conf, &Config{
|
assert.Equal(t, conf, &ConnectionConfig{
|
||||||
CloseHandler: nil,
|
CloseHandler: nil,
|
||||||
WriteTimeout: 30 * time.Second,
|
WriteTimeout: 30 * time.Second,
|
||||||
Retry: GetDefaultRetryConfig(),
|
Retry: GetDefaultRetryConfig(),
|
||||||
@@ -53,8 +53,8 @@ func TestDefaultRetryConfig(t *testing.T) {
|
|||||||
// Config Builder Tests
|
// Config Builder Tests
|
||||||
|
|
||||||
func TestSetConfig(t *testing.T) {
|
func TestSetConfig(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
err := SetConfig(
|
err := applyConnectionOptions(
|
||||||
conf,
|
conf,
|
||||||
WithRetryMaxRetries(0),
|
WithRetryMaxRetries(0),
|
||||||
WithRetryInitialDelay(3*time.Second),
|
WithRetryInitialDelay(3*time.Second),
|
||||||
@@ -67,7 +67,7 @@ func TestSetConfig(t *testing.T) {
|
|||||||
assert.Equal(t, 0.5, conf.Retry.JitterFactor)
|
assert.Equal(t, 0.5, conf.Retry.JitterFactor)
|
||||||
|
|
||||||
// errors propagate
|
// errors propagate
|
||||||
err = SetConfig(
|
err = applyConnectionOptions(
|
||||||
conf,
|
conf,
|
||||||
WithRetryMaxRetries(-10),
|
WithRetryMaxRetries(-10),
|
||||||
)
|
)
|
||||||
@@ -78,118 +78,118 @@ func TestSetConfig(t *testing.T) {
|
|||||||
// Config Option Tests
|
// Config Option Tests
|
||||||
|
|
||||||
func TestWithCloseHandler(t *testing.T) {
|
func TestWithCloseHandler(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
opt := WithCloseHandler(func(code int, text string) error { return nil })
|
opt := WithCloseHandler(func(code int, text string) error { return nil })
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Nil(t, conf.CloseHandler(0, ""))
|
assert.Nil(t, conf.CloseHandler(0, ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithWriteTimeout(t *testing.T) {
|
func TestWithWriteTimeout(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
opt := WithWriteTimeout(30)
|
opt := WithWriteTimeout(30)
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, conf.WriteTimeout, time.Duration(30))
|
assert.Equal(t, conf.WriteTimeout, time.Duration(30))
|
||||||
|
|
||||||
// zero allowed
|
// zero allowed
|
||||||
conf = &Config{}
|
conf = &ConnectionConfig{}
|
||||||
opt = WithWriteTimeout(0)
|
opt = WithWriteTimeout(0)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, conf.WriteTimeout, time.Duration(0))
|
assert.Equal(t, conf.WriteTimeout, time.Duration(0))
|
||||||
|
|
||||||
// negative disallowed
|
// negative disallowed
|
||||||
conf = &Config{}
|
conf = &ConnectionConfig{}
|
||||||
opt = WithWriteTimeout(-30)
|
opt = WithWriteTimeout(-30)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidWriteTimeout)
|
assert.ErrorIs(t, err, errors.InvalidWriteTimeout)
|
||||||
assert.ErrorContains(t, err, "write timeout must be positive")
|
assert.ErrorContains(t, err, "write timeout must be positive")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithRetry(t *testing.T) {
|
func TestWithRetry(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
opt := WithRetry()
|
opt := WithRetry()
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, conf.Retry)
|
assert.NotNil(t, conf.Retry)
|
||||||
assert.Equal(t, conf.Retry, GetDefaultRetryConfig())
|
assert.Equal(t, conf.Retry, GetDefaultRetryConfig())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithRetryAttempts(t *testing.T) {
|
func TestWithRetryAttempts(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
opt := WithRetryMaxRetries(3)
|
opt := WithRetryMaxRetries(3)
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 3, conf.Retry.MaxRetries)
|
assert.Equal(t, 3, conf.Retry.MaxRetries)
|
||||||
|
|
||||||
// zero allowed
|
// zero allowed
|
||||||
opt = WithRetryMaxRetries(0)
|
opt = WithRetryMaxRetries(0)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// negative disallowed
|
// negative disallowed
|
||||||
opt = WithRetryMaxRetries(-10)
|
opt = WithRetryMaxRetries(-10)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryMaxRetries)
|
assert.ErrorIs(t, err, errors.InvalidRetryMaxRetries)
|
||||||
assert.ErrorContains(t, err, "max retry count cannot be negative")
|
assert.ErrorContains(t, err, "max retry count cannot be negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithRetryInitialDelay(t *testing.T) {
|
func TestWithRetryInitialDelay(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
opt := WithRetryInitialDelay(10 * time.Second)
|
opt := WithRetryInitialDelay(10 * time.Second)
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 10*time.Second, conf.Retry.InitialDelay)
|
assert.Equal(t, 10*time.Second, conf.Retry.InitialDelay)
|
||||||
|
|
||||||
// zero disallowed
|
// zero disallowed
|
||||||
opt = WithRetryInitialDelay(0 * time.Second)
|
opt = WithRetryInitialDelay(0 * time.Second)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryInitialDelay)
|
assert.ErrorIs(t, err, errors.InvalidRetryInitialDelay)
|
||||||
assert.ErrorContains(t, err, "initial delay must be positive")
|
assert.ErrorContains(t, err, "initial delay must be positive")
|
||||||
|
|
||||||
// negative disallowed
|
// negative disallowed
|
||||||
opt = WithRetryInitialDelay(-10 * time.Second)
|
opt = WithRetryInitialDelay(-10 * time.Second)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryInitialDelay)
|
assert.ErrorIs(t, err, errors.InvalidRetryInitialDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithRetryMaxDelay(t *testing.T) {
|
func TestWithRetryMaxDelay(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
opt := WithRetryMaxDelay(10 * time.Second)
|
opt := WithRetryMaxDelay(10 * time.Second)
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 10*time.Second, conf.Retry.MaxDelay)
|
assert.Equal(t, 10*time.Second, conf.Retry.MaxDelay)
|
||||||
|
|
||||||
// zero disallowed
|
// zero disallowed
|
||||||
opt = WithRetryMaxDelay(0 * time.Second)
|
opt = WithRetryMaxDelay(0 * time.Second)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryMaxDelay)
|
assert.ErrorIs(t, err, errors.InvalidRetryMaxDelay)
|
||||||
assert.ErrorContains(t, err, "max delay must be positive")
|
assert.ErrorContains(t, err, "max delay must be positive")
|
||||||
|
|
||||||
// negative disallowed
|
// negative disallowed
|
||||||
opt = WithRetryMaxDelay(-10 * time.Second)
|
opt = WithRetryMaxDelay(-10 * time.Second)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryMaxDelay)
|
assert.ErrorIs(t, err, errors.InvalidRetryMaxDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithRetryJitterFactor(t *testing.T) {
|
func TestWithRetryJitterFactor(t *testing.T) {
|
||||||
conf := &Config{}
|
conf := &ConnectionConfig{}
|
||||||
|
|
||||||
opt := WithRetryJitterFactor(0.2)
|
opt := WithRetryJitterFactor(0.2)
|
||||||
err := SetConfig(conf, opt)
|
err := applyConnectionOptions(conf, opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 0.2, conf.Retry.JitterFactor)
|
assert.Equal(t, 0.2, conf.Retry.JitterFactor)
|
||||||
|
|
||||||
// negative disallowed
|
// negative disallowed
|
||||||
opt = WithRetryJitterFactor(-1)
|
opt = WithRetryJitterFactor(-1)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryJitterFactor)
|
assert.ErrorIs(t, err, errors.InvalidRetryJitterFactor)
|
||||||
assert.ErrorContains(t, err, "jitter factor must be between 0.0 and 1.0")
|
assert.ErrorContains(t, err, "jitter factor must be between 0.0 and 1.0")
|
||||||
|
|
||||||
// >1 disallowed
|
// >1 disallowed
|
||||||
opt = WithRetryJitterFactor(1.1)
|
opt = WithRetryJitterFactor(1.1)
|
||||||
err = SetConfig(conf, opt)
|
err = applyConnectionOptions(conf, opt)
|
||||||
assert.ErrorIs(t, err, errors.InvalidRetryJitterFactor)
|
assert.ErrorIs(t, err, errors.InvalidRetryJitterFactor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,21 +198,21 @@ func TestWithRetryJitterFactor(t *testing.T) {
|
|||||||
func TestValidateConfig(t *testing.T) {
|
func TestValidateConfig(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
conf Config
|
conf ConnectionConfig
|
||||||
wantErr error
|
wantErr error
|
||||||
wantErrText string
|
wantErrText string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid empty",
|
name: "valid empty",
|
||||||
conf: *&Config{},
|
conf: *&ConnectionConfig{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid defaults",
|
name: "valid defaults",
|
||||||
conf: *GetDefaultConfig(),
|
conf: *GetDefaultConnectionConfig(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid complete",
|
name: "valid complete",
|
||||||
conf: Config{
|
conf: ConnectionConfig{
|
||||||
CloseHandler: (func(code int, text string) error { return nil }),
|
CloseHandler: (func(code int, text string) error { return nil }),
|
||||||
WriteTimeout: time.Duration(30),
|
WriteTimeout: time.Duration(30),
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
@@ -225,7 +225,7 @@ func TestValidateConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid - initial delay > max delay",
|
name: "invalid - initial delay > max delay",
|
||||||
conf: Config{
|
conf: ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
InitialDelay: 10 * time.Second,
|
InitialDelay: 10 * time.Second,
|
||||||
MaxDelay: 1 * time.Second,
|
MaxDelay: 1 * time.Second,
|
||||||
@@ -237,7 +237,7 @@ func TestValidateConfig(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
err := ValidateConfig(&tc.conf)
|
err := validateConnectionConfig(&tc.conf)
|
||||||
|
|
||||||
if tc.wantErr != nil || tc.wantErrText != "" {
|
if tc.wantErr != nil || tc.wantErrText != "" {
|
||||||
if tc.wantErr != nil {
|
if tc.wantErr != nil {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type Connection struct {
|
|||||||
url *url.URL
|
url *url.URL
|
||||||
dialer Dialer
|
dialer Dialer
|
||||||
socket Socket
|
socket Socket
|
||||||
config *Config
|
config *ConnectionConfig
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
|
|
||||||
incoming chan []byte
|
incoming chan []byte
|
||||||
@@ -54,12 +54,12 @@ type Connection struct {
|
|||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnection(urlStr string, config *Config, logger *slog.Logger) (*Connection, error) {
|
func NewConnection(urlStr string, config *ConnectionConfig, logger *slog.Logger) (*Connection, error) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = GetDefaultConfig()
|
config = GetDefaultConnectionConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateConfig(config); err != nil {
|
if err := validateConnectionConfig(config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,16 +84,16 @@ func NewConnection(urlStr string, config *Config, logger *slog.Logger) (*Connect
|
|||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnectionFromSocket(socket Socket, config *Config, logger *slog.Logger) (*Connection, error) {
|
func NewConnectionFromSocket(socket Socket, config *ConnectionConfig, logger *slog.Logger) (*Connection, error) {
|
||||||
if socket == nil {
|
if socket == nil {
|
||||||
return nil, errors.NewConnectionError("socket cannot be nil")
|
return nil, errors.NewConnectionError("socket cannot be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = GetDefaultConfig()
|
config = GetDefaultConnectionConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateConfig(config); err != nil {
|
if err := validateConnectionConfig(config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ func TestStartWriter(t *testing.T) {
|
|||||||
t.Skip("skipping test in short mode")
|
t.Skip("skipping test in short mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &Config{WriteTimeout: 0}
|
config := &ConnectionConfig{WriteTimeout: 0}
|
||||||
|
|
||||||
outgoingData := make(chan mockOutgoingData, 10)
|
outgoingData := make(chan mockOutgoingData, 10)
|
||||||
mockSocket := NewMockSocket()
|
mockSocket := NewMockSocket()
|
||||||
@@ -166,7 +166,7 @@ func TestStartWriter(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("write timeout sets deadline when positive", func(t *testing.T) {
|
t.Run("write timeout sets deadline when positive", func(t *testing.T) {
|
||||||
config := &Config{WriteTimeout: 30 * time.Millisecond}
|
config := &ConnectionConfig{WriteTimeout: 30 * time.Millisecond}
|
||||||
|
|
||||||
outgoingData := make(chan mockOutgoingData, 10)
|
outgoingData := make(chan mockOutgoingData, 10)
|
||||||
mockSocket := NewMockSocket()
|
mockSocket := NewMockSocket()
|
||||||
@@ -212,7 +212,7 @@ func TestStartWriter(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("writer exits on deadline error", func(t *testing.T) {
|
t.Run("writer exits on deadline error", func(t *testing.T) {
|
||||||
config := &Config{WriteTimeout: 1 * time.Millisecond}
|
config := &ConnectionConfig{WriteTimeout: 1 * time.Millisecond}
|
||||||
|
|
||||||
mockSocket := NewMockSocket()
|
mockSocket := NewMockSocket()
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func TestNewConnection(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
url string
|
url string
|
||||||
config *Config
|
config *ConnectionConfig
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantErrText string
|
wantErrText string
|
||||||
}{
|
}{
|
||||||
@@ -62,7 +62,7 @@ func TestNewConnection(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "valid url, valid config",
|
name: "valid url, valid config",
|
||||||
url: "wss://relay.example.com:8080/path",
|
url: "wss://relay.example.com:8080/path",
|
||||||
config: &Config{WriteTimeout: 30 * time.Second},
|
config: &ConnectionConfig{WriteTimeout: 30 * time.Second},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid url",
|
name: "invalid url",
|
||||||
@@ -74,7 +74,7 @@ func TestNewConnection(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "invalid config",
|
name: "invalid config",
|
||||||
url: "ws://example.com",
|
url: "ws://example.com",
|
||||||
config: &Config{
|
config: &ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
InitialDelay: 10 * time.Second,
|
InitialDelay: 10 * time.Second,
|
||||||
MaxDelay: 1 * time.Second,
|
MaxDelay: 1 * time.Second,
|
||||||
@@ -115,7 +115,7 @@ func TestNewConnection(t *testing.T) {
|
|||||||
|
|
||||||
// Verify default config is used if nil is passed
|
// Verify default config is used if nil is passed
|
||||||
if tc.config == nil {
|
if tc.config == nil {
|
||||||
assert.Equal(t, GetDefaultConfig(), conn.config)
|
assert.Equal(t, GetDefaultConnectionConfig(), conn.config)
|
||||||
} else {
|
} else {
|
||||||
assert.Equal(t, tc.config, conn.config)
|
assert.Equal(t, tc.config, conn.config)
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ func TestNewConnectionFromSocket(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
socket Socket
|
socket Socket
|
||||||
config *Config
|
config *ConnectionConfig
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantErrText string
|
wantErrText string
|
||||||
}{
|
}{
|
||||||
@@ -146,12 +146,12 @@ func TestNewConnectionFromSocket(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "valid socket with valid config",
|
name: "valid socket with valid config",
|
||||||
socket: NewMockSocket(),
|
socket: NewMockSocket(),
|
||||||
config: &Config{WriteTimeout: 30 * time.Second},
|
config: &ConnectionConfig{WriteTimeout: 30 * time.Second},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid config",
|
name: "invalid config",
|
||||||
socket: NewMockSocket(),
|
socket: NewMockSocket(),
|
||||||
config: &Config{
|
config: &ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
InitialDelay: 10 * time.Second,
|
InitialDelay: 10 * time.Second,
|
||||||
MaxDelay: 1 * time.Second,
|
MaxDelay: 1 * time.Second,
|
||||||
@@ -163,7 +163,7 @@ func TestNewConnectionFromSocket(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "close handler set when provided",
|
name: "close handler set when provided",
|
||||||
socket: NewMockSocket(),
|
socket: NewMockSocket(),
|
||||||
config: &Config{
|
config: &ConnectionConfig{
|
||||||
CloseHandler: func(code int, text string) error {
|
CloseHandler: func(code int, text string) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -216,7 +216,7 @@ func TestNewConnectionFromSocket(t *testing.T) {
|
|||||||
|
|
||||||
// Verify default config is used if nil is passed
|
// Verify default config is used if nil is passed
|
||||||
if tc.config == nil {
|
if tc.config == nil {
|
||||||
assert.Equal(t, GetDefaultConfig(), conn.config)
|
assert.Equal(t, GetDefaultConnectionConfig(), conn.config)
|
||||||
} else {
|
} else {
|
||||||
assert.Equal(t, tc.config, conn.config)
|
assert.Equal(t, tc.config, conn.config)
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,7 @@ func TestConnect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("connect retries on dial failure", func(t *testing.T) {
|
t.Run("connect retries on dial failure", func(t *testing.T) {
|
||||||
config := &Config{
|
config := &ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
MaxRetries: 2,
|
MaxRetries: 2,
|
||||||
InitialDelay: 1 * time.Millisecond,
|
InitialDelay: 1 * time.Millisecond,
|
||||||
@@ -325,7 +325,7 @@ func TestConnect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("connect fails after max retries", func(t *testing.T) {
|
t.Run("connect fails after max retries", func(t *testing.T) {
|
||||||
config := &Config{
|
config := &ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
MaxRetries: 2,
|
MaxRetries: 2,
|
||||||
InitialDelay: 1 * time.Millisecond,
|
InitialDelay: 1 * time.Millisecond,
|
||||||
@@ -373,7 +373,7 @@ func TestConnect(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("close handler configured when provided", func(t *testing.T) {
|
t.Run("close handler configured when provided", func(t *testing.T) {
|
||||||
handlerSet := false
|
handlerSet := false
|
||||||
config := &Config{
|
config := &ConnectionConfig{
|
||||||
CloseHandler: func(code int, text string) error {
|
CloseHandler: func(code int, text string) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ func TestConnectLogging(t *testing.T) {
|
|||||||
mockHandler := newMockSlogHandler()
|
mockHandler := newMockSlogHandler()
|
||||||
logger := slog.New(mockHandler)
|
logger := slog.New(mockHandler)
|
||||||
|
|
||||||
config := &Config{
|
config := &ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
MaxRetries: 2,
|
MaxRetries: 2,
|
||||||
InitialDelay: 1 * time.Millisecond,
|
InitialDelay: 1 * time.Millisecond,
|
||||||
@@ -211,7 +211,7 @@ func TestConnectLogging(t *testing.T) {
|
|||||||
mockHandler := newMockSlogHandler()
|
mockHandler := newMockSlogHandler()
|
||||||
logger := slog.New(mockHandler)
|
logger := slog.New(mockHandler)
|
||||||
|
|
||||||
config := &Config{
|
config := &ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
MaxRetries: 3,
|
MaxRetries: 3,
|
||||||
InitialDelay: 1 * time.Millisecond,
|
InitialDelay: 1 * time.Millisecond,
|
||||||
@@ -348,7 +348,7 @@ func TestWriterLogging(t *testing.T) {
|
|||||||
mockHandler := newMockSlogHandler()
|
mockHandler := newMockSlogHandler()
|
||||||
logger := slog.New(mockHandler)
|
logger := slog.New(mockHandler)
|
||||||
|
|
||||||
config := &Config{WriteTimeout: 1 * time.Millisecond}
|
config := &ConnectionConfig{WriteTimeout: 1 * time.Millisecond}
|
||||||
|
|
||||||
deadlineErr := fmt.Errorf("deadline error")
|
deadlineErr := fmt.Errorf("deadline error")
|
||||||
mockSocket := NewMockSocket()
|
mockSocket := NewMockSocket()
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ type mockOutgoingData struct {
|
|||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTestConnection(t *testing.T, config *Config) (
|
func setupTestConnection(t *testing.T, config *ConnectionConfig) (
|
||||||
conn *Connection,
|
conn *Connection,
|
||||||
mockSocket *MockSocket,
|
mockSocket *MockSocket,
|
||||||
incomingData chan mockIncomingData,
|
incomingData chan mockIncomingData,
|
||||||
|
|||||||
8
pool.go
8
pool.go
@@ -62,7 +62,7 @@ type pool struct {
|
|||||||
errors chan error
|
errors chan error
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
|
|
||||||
config *Config
|
config *ConnectionConfig
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
|
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
@@ -131,12 +131,12 @@ type OutboundPool struct {
|
|||||||
dialer Dialer
|
dialer Dialer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOutboundPool(config *Config, logger *slog.Logger) (*OutboundPool, error) {
|
func NewOutboundPool(config *ConnectionConfig, logger *slog.Logger) (*OutboundPool, error) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = GetDefaultConfig()
|
config = GetDefaultConnectionConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateConfig(config); err != nil {
|
if err := validateConnectionConfig(config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ func TestPoolConnect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("fails to add connection", func(t *testing.T) {
|
t.Run("fails to add connection", func(t *testing.T) {
|
||||||
pool, err := NewOutboundPool(&Config{
|
pool, err := NewOutboundPool(&ConnectionConfig{
|
||||||
Retry: &RetryConfig{
|
Retry: &RetryConfig{
|
||||||
MaxRetries: 1,
|
MaxRetries: 1,
|
||||||
InitialDelay: 1 * time.Millisecond,
|
InitialDelay: 1 * time.Millisecond,
|
||||||
|
|||||||
Reference in New Issue
Block a user