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 }