MCPcopy
hub / github.com/caddyserver/caddy / Write

Method Write

modules/logging/netwriter.go:169–215  ·  view source on GitHub ↗

Write wraps the underlying Conn.Write method, but if that fails, it will re-dial the connection anew and try writing again.

(b []byte)

Source from the content-addressed store, hash-verified

167// Write wraps the underlying Conn.Write method, but if that fails,
168// it will re-dial the connection anew and try writing again.
169func (reconn *redialerConn) Write(b []byte) (n int, err error) {
170 reconn.connMu.RLock()
171 conn := reconn.Conn
172 reconn.connMu.RUnlock()
173 if conn != nil {
174 if n, err = conn.Write(b); err == nil {
175 return n, err
176 }
177 }
178
179 // problem with the connection - lock it and try to fix it
180 reconn.connMu.Lock()
181 defer reconn.connMu.Unlock()
182
183 // if multiple concurrent writes failed on the same broken conn, then
184 // one of them might have already re-dialed by now; try writing again
185 if reconn.Conn != nil {
186 if n, err = reconn.Conn.Write(b); err == nil {
187 return n, err
188 }
189 }
190
191 // there's still a problem, so try to re-attempt dialing the socket
192 // if some time has passed in which the issue could have potentially
193 // been resolved - we don't want to block at every single log
194 // emission (!) - see discussion in #4111
195 if time.Since(reconn.lastRedial) > 10*time.Second {
196 reconn.lastRedial = time.Now()
197 conn2, err2 := reconn.dial()
198 if err2 != nil {
199 // logger socket still offline; instead of discarding the log, dump it to stderr
200 os.Stderr.Write(b)
201 return n, err
202 }
203 if n, err = conn2.Write(b); err == nil {
204 if reconn.Conn != nil {
205 reconn.Conn.Close()
206 }
207 reconn.Conn = conn2
208 }
209 } else {
210 // last redial attempt was too recent; just dump to stderr for now
211 os.Stderr.Write(b)
212 }
213
214 return n, err
215}
216
217func (reconn *redialerConn) dial() (net.Conn, error) {
218 return net.DialTimeout(reconn.nw.addr.Network, reconn.nw.addr.JoinHostPort(0), reconn.timeout)

Calls 2

dialMethod · 0.95
CloseMethod · 0.45