etcd/clientv3/remote_client.go
2016-05-12 20:50:58 -07:00

80 lines
1.9 KiB
Go

// Copyright 2016 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package clientv3
import (
"sync"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
type remoteClient struct {
client *Client
conn *grpc.ClientConn
updateConn func(*grpc.ClientConn)
mu sync.Mutex
}
func newRemoteClient(client *Client, update func(*grpc.ClientConn)) *remoteClient {
ret := &remoteClient{
client: client,
conn: client.ActiveConnection(),
updateConn: update,
}
ret.mu.Lock()
defer ret.mu.Unlock()
ret.updateConn(ret.conn)
return ret
}
// reconnectWait reconnects the client, returning when connection establishes/fails.
func (r *remoteClient) reconnectWait(ctx context.Context, prevErr error) error {
r.mu.Lock()
updated := r.tryUpdate()
r.mu.Unlock()
if updated {
return nil
}
conn, err := r.client.connWait(ctx, prevErr)
if err == nil {
r.mu.Lock()
r.conn = conn
r.updateConn(conn)
r.mu.Unlock()
}
return err
}
// reconnect will reconnect the client without waiting
func (r *remoteClient) reconnect(err error) {
r.mu.Lock()
defer r.mu.Unlock()
if r.tryUpdate() {
return
}
r.client.connStartRetry(err)
}
func (r *remoteClient) tryUpdate() bool {
activeConn := r.client.ActiveConnection()
if activeConn == nil || activeConn == r.conn {
return false
}
r.conn = activeConn
r.updateConn(activeConn)
return true
}