@@ -53,17 +53,38 @@ func (p *Pool) handleError(err error) {
53
53
return
54
54
}
55
55
56
- go p .Opts .ErrorHandler (err )
56
+ p .wg .Add (1 )
57
+ go func () {
58
+ defer p .wg .Done ()
59
+ p .Opts .ErrorHandler (err )
60
+ }()
57
61
}
58
62
59
63
// Connect creates poll of connections by calling Factory method and connect them all
60
64
func (p * Pool ) Connect () error {
65
+ // We need to close pool (with all potentially running goroutines) if
66
+ // connection creation fails. Example of such situation is when we
67
+ // successfully created 2 connections, but 3rd failed and minimum
68
+ // connections is 3.
69
+ // Because `Close` uses same mutex as `Connect` we need to unlock it
70
+ // before calling `Close`. That's why we use `connectErr` variable and
71
+ // `defer` statement here, before the next `defer` which unlocks mutex.
72
+ var connectErr error
73
+ defer func () {
74
+ if connectErr != nil {
75
+ p .Close ()
76
+ }
77
+ }()
78
+
61
79
p .mu .Lock ()
62
80
defer p .mu .Unlock ()
63
81
if p .isClosed {
64
82
return errors .New ("pool is closed" )
65
83
}
66
84
85
+ // errors from initial connections creation
86
+ var errs []error
87
+
67
88
// build connections
68
89
for _ , addr := range p .Addrs {
69
90
conn , err := p .Factory (addr )
@@ -76,7 +97,8 @@ func (p *Pool) Connect() error {
76
97
77
98
err = conn .Connect ()
78
99
if err != nil {
79
- p .handleError (fmt .Errorf ("connecting to %s: %w" , conn .addr , err ))
100
+ errs = append (errs , fmt .Errorf ("connecting to %s: %w" , addr , err ))
101
+ p .handleError (fmt .Errorf ("failed to connect to %s: %w" , conn .addr , err ))
80
102
p .wg .Add (1 )
81
103
go p .recreateConnection (conn )
82
104
continue
@@ -85,11 +107,16 @@ func (p *Pool) Connect() error {
85
107
p .connections = append (p .connections , conn )
86
108
}
87
109
88
- if len (p .connections ) < p .Opts .MinConnections {
89
- return fmt . Errorf ( "minimum %d connections is required, established: %d" , p . Opts . MinConnections , len ( p . connections ))
110
+ if len (p .connections ) >= p .Opts .MinConnections {
111
+ return nil
90
112
}
91
113
92
- return nil
114
+ if len (errs ) == 0 {
115
+ connectErr = fmt .Errorf ("minimum %d connections is required, established: %d" , p .Opts .MinConnections , len (p .connections ))
116
+ } else {
117
+ connectErr = fmt .Errorf ("minimum %d connections is required, established: %d, errors: %w" , p .Opts .MinConnections , len (p .connections ), errors .Join (errs ... ))
118
+ }
119
+ return connectErr
93
120
}
94
121
95
122
// Connections returns copy of all connections from the pool
0 commit comments