code: func (c *Client) cleanup(err error, doClose bool, possiblyClosed bool) error {
  	// cancel connect future if appropriate
  	if atomic.LoadUint32(&c.state) < clientConnacked && c.connectFuture != nil {
  		c.connectFuture.Cancel()
  	}
  
  	// set state
  	atomic.StoreUint32(&c.state, clientDisconnected)
  
  	// ensure that the connection gets closed
  	if doClose {
  		connErr := c.conn.Close()
  		if connErr != nil && err == nil && !possiblyClosed {
  			err = connErr
  		}
  	}
  
  	// reset store
  	if c.clean {
  		sessErr := c.Session.Reset()
  		if sessErr != nil && err == nil {
  			err = sessErr
  		}
  	}
  
  	// cancel all futures
  	c.futureStore.Clear()
  
  	return err
  }
docs: // will try to cleanup as many resources as possible