Add error check for waitQueueTimeout in the stable API

XMLWordPrintableJSON

    • Type: New Feature
    • Resolution: Won't Do
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: Error Handling
    • None
    • 🔵 Done
    • Go Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      The only way to verify that an error returned by an operation is due to a waitQueue timeout is to see if the first error in err's tree that matches topology.WaitQueueTimeoutError:

      var wqtErr topology.WaitQueueTimeoutError
      if errors.As(err, &wqtErr) {
          // Handle waitQueue timeout error
      }
      

      It would be convenient if there was a direct programatic solution for this that did not depend on the experimental API.

      See test case here: https://gist.github.com/prestonvasquez/c97117e516236da3cb6c31e4a23a91ba

      Definition of Done

      Option 1: Add a helper function

      // IsWaitQueueTimeout returns true if err is a wait queue timeout error, which occurs when
      // checking out a connection from the pool times out.
      func IsWaitQueueTimeout(err error) bool {
      	return errors.As(err, &topology.WaitQueueTimeoutError{})
      }
      

      Option 2: Add a stable type

      // WaitQueueTimeoutError is returned when a connection checkout from the pool times out.
      type WaitQueueTimeoutError struct {
          Wrapped              error         // The underlying timeout error
          MaxPoolSize          uint64        // The maximum pool size
          TotalConnections     int           // Total number of connections in the pool
          AvailableConnections int           // Number of idle connections
          WaitDuration         time.Duration // How long the operation waited
      
          // For load-balanced mode only
          PinnedCursorConnections      *uint64
          PinnedTransactionConnections *uint64
      
          // Internal flag for error message formatting
          wrappedMsgOnly bool
      }
      
      func (w WaitQueueTimeoutError) Error() string {
          // If wrapped by wrapErrors, just return wrapped error message
          if w.wrappedMsgOnly {
              return w.Wrapped.Error()
          }
          
          // Otherwise build the full error message
          // ... (delegate to wrapped error's Error method or build similar format)
      }
      
      func (w WaitQueueTimeoutError) Unwrap() error {
          return w.Wrapped
      }
      

      Pitfalls

      This addition further extends our errors api for a niche use case that can be achieved with the experimental API, which is arguably where it belongs.

            Assignee:
            Unassigned
            Reporter:
            Preston Vasquez
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: