Proposal Details
Proposal: Add the following to the net package:
// ErrRetryableAcceptError indicates a Listener.Accept error may be transient,
// and that a future call to Accept may succeed. This error is usually wrapped
// in another error, and should be tested for with errors.Is(err, ErrRetryableAcceptError).
//
// Accept errors corresponding to the errno values EMFILE, ENFILE, ECONNRESET, and ECONNABORTED
// match this error.
var ErrRetryableAcceptError = errors.New("ErrRetryableAcceptError")
Implementation will be to add an Is method to net.OpError which performs the appropriate check.
Background/rationale:
Some of the errors returned by net.Listener.Accept are potentially transient: While they indicate that the Accept call has failed, a future call may succeed.
Examples include:
A server which calls Accept may want to ignore all these errors and call Accept again, probably after some backoff period. One of the uses for the deprecated net.Error.Temporary method is to check for these conditions, since we report all of the above as "temporary" errors.
As an example, net/http.Server uses net.Error.Temporary to retry potentially-transient Accept errors.
With the deprecation of net.Error.Temporary there is no non-deprecated way to test for these conditions. Temporary was deprecated, not because it isn't useful to test for retryable Accept errors but because the Temporary condition was ill-defined for many other errors, conflated transient errors with timeouts, and was just generally misunderstood. (See #45729.) I propose adding ErrRetryableAcceptError to provide a focused and reasonable well-defined replacement for the specific use case of Accept loops.
As an alternative, it might be nice if Accept just worked and didn't require the user to check for transient errors. However, that would require changing long-established behavior, and defining correct handling of EMFILE (for one example) seems challenging. This proposal is less ambitious in scope.
Further references:
Proposal Details
Proposal: Add the following to the
netpackage:Implementation will be to add an
Ismethod tonet.OpErrorwhich performs the appropriate check.Background/rationale:
Some of the errors returned by
net.Listener.Acceptare potentially transient: While they indicate that theAcceptcall has failed, a future call may succeed.Examples include:
EMFILE: the process is out of file descriptorsENFILE: the system is out of file descriptorsECONNRESETandECONNABORTED: see net/http: possible issues with temporary errors from Accept #6163A server which calls
Acceptmay want to ignore all these errors and callAcceptagain, probably after some backoff period. One of the uses for the deprecatednet.Error.Temporarymethod is to check for these conditions, since we report all of the above as "temporary" errors.As an example,
net/http.Serverusesnet.Error.Temporaryto retry potentially-transientAccepterrors.With the deprecation of
net.Error.Temporarythere is no non-deprecated way to test for these conditions.Temporarywas deprecated, not because it isn't useful to test for retryableAccepterrors but because theTemporarycondition was ill-defined for many other errors, conflated transient errors with timeouts, and was just generally misunderstood. (See #45729.) I propose addingErrRetryableAcceptErrorto provide a focused and reasonable well-defined replacement for the specific use case ofAcceptloops.As an alternative, it might be nice if
Acceptjust worked and didn't require the user to check for transient errors. However, that would require changing long-established behavior, and defining correct handling ofEMFILE(for one example) seems challenging. This proposal is less ambitious in scope.Further references: