gitee.com/curryzheng/dm@v0.0.1/y.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_PRIMARY_ONLY:
   103  		if ep.serverMode != SERVER_MODE_PRIMARY {
   104  			return SORT_SERVER_MODE_INVALID
   105  		}
   106  		sort += SORT_PRIMARY
   107  	case LOGIN_MODE_STANDBY_ONLY:
   108  		if ep.serverMode != SERVER_MODE_STANDBY {
   109  			return SORT_SERVER_MODE_INVALID
   110  		}
   111  		sort += SORT_STANDBY
   112  	}
   113  
   114  	switch ep.serverStatus {
   115  	case SERVER_STATUS_MOUNT:
   116  		sort += SORT_MOUNT
   117  	case SERVER_STATUS_OPEN:
   118  		sort += SORT_OPEN
   119  	case SERVER_STATUS_SUSPEND:
   120  		sort += SORT_SUSPEND
   121  	}
   122  	return sort
   123  }
   124  
   125  func (ep *ep) refreshStatus(alive bool, conn *DmConnection) {
   126  	ep.lock.Lock()
   127  	defer ep.lock.Unlock()
   128  	ep.alive = alive
   129  	ep.statusRefreshTs = time.Now().UnixNano()
   130  	if alive {
   131  		ep.serverMode = conn.SvrMode
   132  		ep.serverStatus = conn.SvrStat
   133  		ep.dscControl = conn.dscControl
   134  		ep.sort = ep.calcSort(int32(conn.dmConnector.loginMode))
   135  	} else {
   136  		ep.serverMode = -1
   137  		ep.serverStatus = -1
   138  		ep.dscControl = false
   139  		ep.sort = SORT_SERVER_NOT_ALIVE
   140  	}
   141  }
   142  
   143  func (ep *ep) connect(connector *DmConnector) (*DmConnection, error) {
   144  	connector.host = ep.host
   145  	connector.port = ep.port
   146  	conn, err := connector.connectSingle(context.Background())
   147  	if err != nil {
   148  		ep.refreshStatus(false, conn)
   149  		return nil, err
   150  	}
   151  	ep.refreshStatus(true, conn)
   152  	return conn, nil
   153  }
   154  
   155  func (ep *ep) getServerStatusDesc(serverStatus int32) string {
   156  	ret := ""
   157  	switch ep.serverStatus {
   158  	case SERVER_STATUS_OPEN:
   159  		ret = "OPEN"
   160  	case SERVER_STATUS_MOUNT:
   161  		ret = "MOUNT"
   162  	case SERVER_STATUS_SUSPEND:
   163  		ret = "SUSPEND"
   164  	default:
   165  		ret = "UNKNOWN"
   166  	}
   167  	return ret
   168  }
   169  
   170  func (ep *ep) getServerModeDesc(serverMode int32) string {
   171  	ret := ""
   172  	switch ep.serverMode {
   173  	case SERVER_MODE_NORMAL:
   174  		ret = "NORMAL"
   175  	case SERVER_MODE_PRIMARY:
   176  		ret = "PRIMARY"
   177  	case SERVER_MODE_STANDBY:
   178  		ret = "STANDBY"
   179  	default:
   180  		ret = "UNKNOWN"
   181  	}
   182  	return ret
   183  }
   184  
   185  func (ep *ep) String() string {
   186  	dscControl := ")"
   187  	if ep.dscControl {
   188  		dscControl = ", DSC CONTROL)"
   189  	}
   190  	return strings.TrimSpace(ep.host) + ":" + strconv.Itoa(int(ep.port)) +
   191  		" (" + ep.getServerModeDesc(ep.serverMode) + ", " + ep.getServerStatusDesc(ep.serverStatus) + dscControl
   192  }