mirror of https://github.com/grpc/grpc-go.git
				
				
				
			Change errors returned by ac.wait()
This commit is contained in:
		
							parent
							
								
									cd5721c02f
								
							
						
					
					
						commit
						c72b08a774
					
				
							
								
								
									
										4
									
								
								call.go
								
								
								
								
							
							
						
						
									
										4
									
								
								call.go
								
								
								
								
							| 
						 | 
					@ -170,9 +170,9 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
 | 
				
			||||||
			if _, ok := err.(*rpcError); ok {
 | 
								if _, ok := err.(*rpcError); ok {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err == errConnClosing {
 | 
								if err == errConnClosing || err == errConnUnavailable {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					return Errorf(codes.Unavailable, "%v", errConnClosing)
 | 
										return Errorf(codes.Unavailable, "%v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,9 @@ var (
 | 
				
			||||||
	errConnDrain = errors.New("grpc: the connection is drained")
 | 
						errConnDrain = errors.New("grpc: the connection is drained")
 | 
				
			||||||
	// errConnClosing indicates that the connection is closing.
 | 
						// errConnClosing indicates that the connection is closing.
 | 
				
			||||||
	errConnClosing = errors.New("grpc: the connection is closing")
 | 
						errConnClosing = errors.New("grpc: the connection is closing")
 | 
				
			||||||
	errNoAddr      = errors.New("grpc: there is no address available to dial")
 | 
						// errConnUnavailable indicates that the connection is unavailable.
 | 
				
			||||||
 | 
						errConnUnavailable = errors.New("grpc: the connection is unavailable")
 | 
				
			||||||
 | 
						errNoAddr          = errors.New("grpc: there is no address available to dial")
 | 
				
			||||||
	// minimum time to give a connection to complete
 | 
						// minimum time to give a connection to complete
 | 
				
			||||||
	minConnectTimeout = 20 * time.Second
 | 
						minConnectTimeout = 20 * time.Second
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -501,11 +503,7 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil, nil, errConnClosing
 | 
							return nil, nil, errConnClosing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// ac.wait should block on transient failure only if balancer is nil and RPC is non-failfast.
 | 
						t, err := ac.wait(ctx, cc.dopts.balancer != nil, !opts.BlockingWait)
 | 
				
			||||||
	//  - If RPC is failfast, ac.wait should not block.
 | 
					 | 
				
			||||||
	//  - If balancer is not nil, ac.wait should return errConnClosing on transient failure
 | 
					 | 
				
			||||||
	//    so that non-failfast RPCs will try to get a new transport instead of waiting on ac.
 | 
					 | 
				
			||||||
	t, err := ac.wait(ctx, cc.dopts.balancer == nil && opts.BlockingWait)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if put != nil {
 | 
							if put != nil {
 | 
				
			||||||
			put()
 | 
								put()
 | 
				
			||||||
| 
						 | 
					@ -757,36 +755,42 @@ func (ac *addrConn) transportMonitor() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or
 | 
					// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or
 | 
				
			||||||
// iv) transport is in TransientFailure and blocking is false.
 | 
					// iv) transport is in TransientFailure and there's no balancer/failfast is true.
 | 
				
			||||||
func (ac *addrConn) wait(ctx context.Context, blocking bool) (transport.ClientTransport, error) {
 | 
					func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (transport.ClientTransport, error) {
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		ac.mu.Lock()
 | 
							ac.mu.Lock()
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case ac.state == Shutdown:
 | 
							case ac.state == Shutdown:
 | 
				
			||||||
			err := ac.tearDownErr
 | 
								if failfast || !hasBalancer {
 | 
				
			||||||
 | 
									// RPC is failfast or balancer is nil. This RPC should fail with ac.tearDownErr.
 | 
				
			||||||
 | 
									err := ac.tearDownErr
 | 
				
			||||||
 | 
									ac.mu.Unlock()
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			ac.mu.Unlock()
 | 
								ac.mu.Unlock()
 | 
				
			||||||
			return nil, err
 | 
								return nil, errConnClosing
 | 
				
			||||||
		case ac.state == Ready:
 | 
							case ac.state == Ready:
 | 
				
			||||||
			ct := ac.transport
 | 
								ct := ac.transport
 | 
				
			||||||
			ac.mu.Unlock()
 | 
								ac.mu.Unlock()
 | 
				
			||||||
			return ct, nil
 | 
								return ct, nil
 | 
				
			||||||
		case ac.state == TransientFailure && !blocking:
 | 
							case ac.state == TransientFailure:
 | 
				
			||||||
			ac.mu.Unlock()
 | 
								if failfast || hasBalancer {
 | 
				
			||||||
			return nil, errConnClosing
 | 
									ac.mu.Unlock()
 | 
				
			||||||
		default:
 | 
									return nil, errConnUnavailable
 | 
				
			||||||
			ready := ac.ready
 | 
					 | 
				
			||||||
			if ready == nil {
 | 
					 | 
				
			||||||
				ready = make(chan struct{})
 | 
					 | 
				
			||||||
				ac.ready = ready
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			ac.mu.Unlock()
 | 
					 | 
				
			||||||
			select {
 | 
					 | 
				
			||||||
			case <-ctx.Done():
 | 
					 | 
				
			||||||
				return nil, toRPCErr(ctx.Err())
 | 
					 | 
				
			||||||
			// Wait until the new transport is ready or failed.
 | 
					 | 
				
			||||||
			case <-ready:
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ready := ac.ready
 | 
				
			||||||
 | 
							if ready == nil {
 | 
				
			||||||
 | 
								ready = make(chan struct{})
 | 
				
			||||||
 | 
								ac.ready = ready
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ac.mu.Unlock()
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-ctx.Done():
 | 
				
			||||||
 | 
								return nil, toRPCErr(ctx.Err())
 | 
				
			||||||
 | 
							// Wait until the new transport is ready or failed.
 | 
				
			||||||
 | 
							case <-ready:
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -146,9 +146,9 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
 | 
				
			||||||
			if _, ok := err.(*rpcError); ok {
 | 
								if _, ok := err.(*rpcError); ok {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err == errConnClosing {
 | 
								if err == errConnClosing || err == errConnUnavailable {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					return nil, Errorf(codes.Unavailable, "%v", errConnClosing)
 | 
										return nil, Errorf(codes.Unavailable, "%v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue