gitee.com/chunanyong/dm@v1.8.12/x.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 6 package dm 7 8 import ( 9 "context" 10 "strconv" 11 "strings" 12 "sync" 13 "time" 14 ) 15 16 const ( 17 STATUS_VALID_TIME = 20 * time.Second // ms 18 19 // sort 值 20 SORT_SERVER_MODE_INVALID = -1 // 不允许连接的模式 21 22 SORT_SERVER_NOT_ALIVE = -2 // 站点无法连接 23 24 SORT_UNKNOWN = INT32_MAX // 站点还未连接过,模式未知 25 26 SORT_NORMAL = 30 27 28 SORT_PRIMARY = 20 29 30 SORT_STANDBY = 10 31 32 // OPEN>MOUNT>SUSPEND 33 SORT_OPEN = 3 34 35 SORT_MOUNT = 2 36 37 SORT_SUSPEND = 1 38 ) 39 40 type ep struct { 41 host string 42 port int32 43 alive bool 44 statusRefreshTs int64 // 状态更新的时间点 45 serverMode int32 46 serverStatus int32 47 dscControl bool 48 sort int32 49 epSeqno int32 50 epStatus int32 51 lock sync.Mutex 52 } 53 54 func newEP(host string, port int32) *ep { 55 ep := new(ep) 56 ep.host = host 57 ep.port = port 58 ep.serverMode = -1 59 ep.serverStatus = -1 60 ep.sort = SORT_UNKNOWN 61 return ep 62 } 63 64 func (ep *ep) getSort(checkTime bool) int32 { 65 if checkTime { 66 if time.Now().UnixNano()-ep.statusRefreshTs < int64(STATUS_VALID_TIME) { 67 return ep.sort 68 } else { 69 return SORT_UNKNOWN 70 } 71 } 72 return ep.sort 73 } 74 75 func (ep *ep) calcSort(loginMode int32) int32 { 76 var sort int32 = 0 77 switch loginMode { 78 case LOGIN_MODE_PRIMARY_FIRST: 79 { 80 // 主机优先:PRIMARY>NORMAL>STANDBY 81 switch ep.serverMode { 82 case SERVER_MODE_NORMAL: 83 sort += SORT_NORMAL * 10 84 case SERVER_MODE_PRIMARY: 85 sort += SORT_PRIMARY * 100 86 case SERVER_MODE_STANDBY: 87 sort += SORT_STANDBY 88 } 89 } 90 case LOGIN_MODE_STANDBY_FIRST: 91 { 92 // STANDBY优先: STANDBY>PRIMARY>NORMAL 93 switch ep.serverMode { 94 case SERVER_MODE_NORMAL: 95 sort += SORT_NORMAL 96 case SERVER_MODE_PRIMARY: 97 sort += SORT_PRIMARY * 10 98 case SERVER_MODE_STANDBY: 99 sort += SORT_STANDBY * 100 100 } 101 } 102 case LOGIN_MODE_NORMAL_FIRST: 103 { 104 // NORMAL优先: NORMAL>PRIMARY>STANDBY 105 switch ep.serverMode { 106 case SERVER_MODE_STANDBY: 107 sort += SORT_STANDBY 108 case SERVER_MODE_PRIMARY: 109 sort += SORT_PRIMARY * 10 110 case SERVER_MODE_NORMAL: 111 sort += SORT_NORMAL * 100 112 } 113 } 114 case LOGIN_MODE_PRIMARY_ONLY: 115 if ep.serverMode != SERVER_MODE_PRIMARY { 116 return SORT_SERVER_MODE_INVALID 117 } 118 sort += SORT_PRIMARY 119 case LOGIN_MODE_STANDBY_ONLY: 120 if ep.serverMode != SERVER_MODE_STANDBY { 121 return SORT_SERVER_MODE_INVALID 122 } 123 sort += SORT_STANDBY 124 } 125 126 switch ep.serverStatus { 127 case SERVER_STATUS_MOUNT: 128 sort += SORT_MOUNT 129 case SERVER_STATUS_OPEN: 130 sort += SORT_OPEN 131 case SERVER_STATUS_SUSPEND: 132 sort += SORT_SUSPEND 133 } 134 return sort 135 } 136 137 func (ep *ep) refreshStatus(alive bool, conn *DmConnection) { 138 ep.lock.Lock() 139 defer ep.lock.Unlock() 140 ep.alive = alive 141 ep.statusRefreshTs = time.Now().UnixNano() 142 if alive { 143 ep.serverMode = conn.SvrMode 144 ep.serverStatus = conn.SvrStat 145 ep.dscControl = conn.dscControl 146 ep.sort = ep.calcSort(int32(conn.dmConnector.loginMode)) 147 } else { 148 ep.serverMode = -1 149 ep.serverStatus = -1 150 ep.dscControl = false 151 ep.sort = SORT_SERVER_NOT_ALIVE 152 } 153 } 154 155 func (ep *ep) connect(connector *DmConnector) (*DmConnection, error) { 156 connector.host = ep.host 157 connector.port = ep.port 158 conn, err := connector.connectSingle(context.Background()) 159 if err != nil { 160 ep.refreshStatus(false, conn) 161 return nil, err 162 } 163 ep.refreshStatus(true, conn) 164 return conn, nil 165 } 166 167 func (ep *ep) getServerStatusDesc(serverStatus int32) string { 168 ret := "" 169 switch ep.serverStatus { 170 case SERVER_STATUS_OPEN: 171 ret = "OPEN" 172 case SERVER_STATUS_MOUNT: 173 ret = "MOUNT" 174 case SERVER_STATUS_SUSPEND: 175 ret = "SUSPEND" 176 default: 177 ret = "UNKNOWN" 178 } 179 return ret 180 } 181 182 func (ep *ep) getServerModeDesc(serverMode int32) string { 183 ret := "" 184 switch ep.serverMode { 185 case SERVER_MODE_NORMAL: 186 ret = "NORMAL" 187 case SERVER_MODE_PRIMARY: 188 ret = "PRIMARY" 189 case SERVER_MODE_STANDBY: 190 ret = "STANDBY" 191 default: 192 ret = "UNKNOWN" 193 } 194 return ret 195 } 196 197 func (ep *ep) String() string { 198 dscControl := ")" 199 if ep.dscControl { 200 dscControl = ", DSC CONTROL)" 201 } 202 return strings.TrimSpace(ep.host) + ":" + strconv.Itoa(int(ep.port)) + 203 " (" + ep.getServerModeDesc(ep.serverMode) + ", " + ep.getServerStatusDesc(ep.serverStatus) + dscControl 204 }