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  }