前言
定义
type Options struct {
Pipeline pipeline. Pipeline
IsMaster bool
AdvertiseAddr string
RetryInterval time. Duration
ClientAddr string
Components * component. Components
Label string
IsWebsocket bool
TSLCertificate string
TSLKey string
}
type Node struct {
Options
ServiceAddr string
cluster * cluster
handler * LocalHandler
server * grpc. Server
rpcClient * rpcClient
mu sync. RWMutex
sessions map [ int64 ] * session. Session
}
方法
建立节点
func ( n * Node) Startup ( ) error {
if n. ServiceAddr == "" {
return errors. New ( "service address cannot be empty in master node" )
}
n. sessions = map [ int64 ] * session. Session{ }
n. cluster = newCluster ( n)
n. handler = NewHandler ( n, n. Pipeline)
components := n. Components. List ( )
for _ , c := range components {
err := n. handler. register ( c. Comp, c. Opts)
if err != nil {
return err
}
}
cache ( )
if err := n. initNode ( ) ; err != nil {
return err
}
for _ , c := range components {
c. Comp. Init ( )
}
for _ , c := range components {
c. Comp. AfterInit ( )
}
if n. ClientAddr != "" {
go func ( ) {
if n. IsWebsocket {
if len ( n. TSLCertificate) != 0 {
n. listenAndServeWSTLS ( )
} else {
n. listenAndServeWS ( )
}
} else {
n. listenAndServe ( )
}
} ( )
}
return nil
}
初始化节点
func ( n * Node) initNode ( ) error {
if ! n. IsMaster && n. AdvertiseAddr == "" {
return nil
}
listener, err := net. Listen ( "tcp" , n. ServiceAddr)
if err != nil {
return err
}
n. server = grpc. NewServer ( )
n. rpcClient = newRPCClient ( )
clusterpb. RegisterMemberServer ( n. server, n)
go func ( ) {
err := n. server. Serve ( listener)
if err != nil {
log. Fatalf ( "Start current node failed: %v" , err)
}
} ( )
if n. IsMaster {
clusterpb. RegisterMasterServer ( n. server, n. cluster)
member := & Member{
isMaster: true ,
memberInfo: & clusterpb. MemberInfo{
Label: n. Label,
ServiceAddr: n. ServiceAddr,
Services: n. handler. LocalService ( ) ,
} ,
}
n. cluster. members = append ( n. cluster. members, member)
n. cluster. setRpcClient ( n. rpcClient)
} else {
pool, err := n. rpcClient. getConnPool ( n. AdvertiseAddr)
if err != nil {
return err
}
client := clusterpb. NewMasterClient ( pool. Get ( ) )
request := & clusterpb. RegisterRequest{
MemberInfo: & clusterpb. MemberInfo{
Label: n. Label,
ServiceAddr: n. ServiceAddr,
Services: n. handler. LocalService ( ) ,
} ,
}
for {
resp, err := client. Register ( context. Background ( ) , request)
if err == nil {
n. handler. initRemoteService ( resp. Members)
n. cluster. initMembers ( resp. Members)
break
}
log. Println ( "Register current node to cluster failed" , err, "and will retry in" , n. RetryInterval. String ( ) )
time. Sleep ( n. RetryInterval)
}
}
return nil
}
关闭节点
func ( n * Node) Shutdown ( ) {
components := n. Components. List ( )
length := len ( components)
for i := length - 1 ; i >= 0 ; i-- {
components[ i] . Comp. BeforeShutdown ( )
}
for i := length - 1 ; i >= 0 ; i-- {
components[ i] . Comp. Shutdown ( )
}
if ! n. IsMaster && n. AdvertiseAddr != "" {
pool, err := n. rpcClient. getConnPool ( n. AdvertiseAddr)
if err != nil {
log. Println ( "Retrieve master address error" , err)
goto EXIT
}
client := clusterpb. NewMasterClient ( pool. Get ( ) )
request := & clusterpb. UnregisterRequest{
ServiceAddr: n. ServiceAddr,
}
_ , err = client. Unregister ( context. Background ( ) , request)
if err != nil {
log. Println ( "Unregister current node failed" , err)
goto EXIT
}
}
EXIT:
if n. server != nil {
n. server. GracefulStop ( )
}
}