WebSocket client Reconnect middleware
          #7445
        
          
      
                
     Merged
            
            
          
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
This PR introduces a
Reconnectmiddleware for WebSocket clients, a spiritual equivalent to theRetrymiddleware we have for HTTPClients. The idea is to abstract away the retry and reconnect logic behind what presents as a single, persistent connection that withstands network hiccups. I have currently settled on a number of design choices intended to keep the implementation simple and modular.The middleware actually applies to
WSConnectionHighLevelinstead of toWSClient. This enables the user to create their own retry logic for theconnectaction, see design choice (2).Unlike the
Retrymiddleware forClient, this middleware does not implement any sort of retry logic; it will simply attempt toconnectagain immediately. The expectation is that the user will employ e.g. cats-retry to theconnectaction to get backoff, etc.In the same vein, the middleware does not retry failed
sends orreceives; it's up to the user to do that, likely with the help of cats-retry. The middleware simply guarantees that a new connection will have been established between the error and the retriedsend/receive.One caveat of these design choices is that retrying the
connect: Resourceon error is currently complicated by an outstanding Cats Effect issue:Resource#attemptholds onto acquired resources even in case of error typelevel/cats-effect#3757This issue doesn't affect either the JDK or http4s-dom
WSClientimplementations because they establish the entire connection within a singledelay(...). But, this bug would cause the EmberWSClientthat is WIP in #7261 to starve the pool of sockets upon retries. That's because in the Ember implementation, opening a WebSocket connection occurs in two phases: (1) acquiring a socket from the pool and (2) handshaking with the server. Currently, catching an error in phase (2) does not return the socket to the pool that was acquired in phase (1). In any case, I think we've decided this behavior is undesirable and will ship a fix in CE 3.6.