vitess.io/vitess@v0.16.2/go/vt/topo/zk2topo/server.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package zk2topo
    18  
    19  import (
    20  	"strings"
    21  
    22  	"vitess.io/vitess/go/vt/topo"
    23  )
    24  
    25  const (
    26  	// Path elements
    27  	locksPath     = "locks"
    28  	electionsPath = "elections"
    29  )
    30  
    31  // Factory is the zookeeper topo.Factory implementation.
    32  type Factory struct{}
    33  
    34  // hasObservers checks the provided address to see if it has observers.
    35  // If so, it returns the voting server address, the observer address, and true.
    36  // Otherwise, it returns false.
    37  func hasObservers(serverAddr string) (string, string, bool) {
    38  	if i := strings.Index(serverAddr, "|"); i != -1 {
    39  		return serverAddr[:i], serverAddr[i+1:], true
    40  	}
    41  	return "", "", false
    42  }
    43  
    44  // HasGlobalReadOnlyCell is part of the topo.Factory interface.
    45  //
    46  // Further implementation design note: Zookeeper supports Observers:
    47  // https://zookeeper.apache.org/doc/trunk/zookeeperObservers.html
    48  // To use them, follow these instructions:
    49  //   - setup your observer servers as described in the previous link.
    50  //   - specify a second set of servers in serverAddr, after a '|', like:
    51  //     global1:port1,global2:port2|observer1:port1,observer2:port2
    52  //   - if HasGlobalReadOnlyCell detects that the serverAddr has both lists,
    53  //     it returns true.
    54  //   - the Create method below also splits the values, and if
    55  //     cell is GlobalCell, use the left side, if cell is GlobalReadOnlyCell,
    56  //     use the right side.
    57  func (f Factory) HasGlobalReadOnlyCell(serverAddr, root string) bool {
    58  	_, _, ok := hasObservers(serverAddr)
    59  	return ok
    60  }
    61  
    62  // Create is part of the topo.Factory interface.
    63  func (f Factory) Create(cell, serverAddr, root string) (topo.Conn, error) {
    64  	if cell == topo.GlobalCell {
    65  		// For the global cell, extract the voting servers if we
    66  		// have observers.
    67  		newAddr, _, ok := hasObservers(serverAddr)
    68  		if ok {
    69  			serverAddr = newAddr
    70  		}
    71  	}
    72  	if cell == topo.GlobalReadOnlyCell {
    73  		// Use the observers as serverAddr.
    74  		_, serverAddr, _ = hasObservers(serverAddr)
    75  	}
    76  	return NewServer(serverAddr, root), nil
    77  }
    78  
    79  // Server is the zookeeper topo.Conn implementation.
    80  type Server struct {
    81  	root string
    82  	conn *ZkConn
    83  }
    84  
    85  // NewServer returns a topo.Conn connecting to real Zookeeper processes.
    86  func NewServer(serverAddr, root string) *Server {
    87  	return &Server{
    88  		root: root,
    89  		conn: Connect(serverAddr),
    90  	}
    91  }
    92  
    93  // Close is part of topo.Conn interface.
    94  func (zs *Server) Close() {
    95  	zs.conn.Close()
    96  	zs.conn = nil
    97  }
    98  func init() {
    99  	topo.RegisterFactory("zk2", Factory{})
   100  }