Commit 897bd5a7 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 775fce3a
...@@ -77,9 +77,9 @@ type _MasteredNode struct { ...@@ -77,9 +77,9 @@ type _MasteredNode struct {
opReady chan struct{} // reinitialized each time state becomes non-operational opReady chan struct{} // reinitialized each time state becomes non-operational
operational bool // cache for state.IsOperational() operational bool // cache for state.IsOperational()
flags _MasteredNodeFlags
rxm chan _RxM // TalkMaster -> RecvM1 rxm chan _RxM // TalkMaster -> RecvM1
rxmFlags _MasteredNodeFlags // if e.g. δPartTab messages should be delivered to RecvM1
// XXX just use `.myInfo.NodeType == STORAGE` instead?
} }
// _RxM represents a request or event received from master. // _RxM represents a request or event received from master.
...@@ -133,9 +133,9 @@ func newMasteredNode(typ proto.NodeType, clusterName string, net xnet.Networker, ...@@ -133,9 +133,9 @@ func newMasteredNode(typ proto.NodeType, clusterName string, net xnet.Networker,
// Notifications to node/partition tables and cluster state are automatically // Notifications to node/partition tables and cluster state are automatically
// handled, while other notifications and requests are passed through to RecvM1. // handled, while other notifications and requests are passed through to RecvM1.
// //
// The connection to master is persisted by redial as needed. // Master link is persisted by redialing as needed.
// //
// f is called on every reconnection after identification and protocol prologue. // f is called on every reconnection to master after identification and protocol prologue.
// //
// See top-level _MasteredNode overview for details. // See top-level _MasteredNode overview for details.
// //
...@@ -156,6 +156,9 @@ func (node *_MasteredNode) TalkMaster(ctx context.Context, f func(context.Contex ...@@ -156,6 +156,9 @@ func (node *_MasteredNode) TalkMaster(ctx context.Context, f func(context.Contex
defer task.Runningf(&ctx, "%s: talk master(%s)", me0, node.MasterAddr)(&err) defer task.Runningf(&ctx, "%s: talk master(%s)", me0, node.MasterAddr)(&err)
for { for {
node.updateOperational(func() {
node.mlink = nil
})
err := node.talkMaster1(ctx, ctx0, f) err := node.talkMaster1(ctx, ctx0, f)
log.Warning(ctx, err) // XXX Warning ok? -> Error? log.Warning(ctx, err) // XXX Warning ok? -> Error?
// TODO if err == "reject identification / protocol error" -> shutdown client // TODO if err == "reject identification / protocol error" -> shutdown client
...@@ -221,24 +224,19 @@ func (node *_MasteredNode) talkMaster1(ctx, ctxPreTalkM context.Context, f func( ...@@ -221,24 +224,19 @@ func (node *_MasteredNode) talkMaster1(ctx, ctxPreTalkM context.Context, f func(
// update cluster state // update cluster state
// XXX locking node.updateOperational(func() {
node.opMu.Lock() err = node.updateNodeTab(ctx, &mnt) // the only err is cmdShutdown
err = node.updateNodeTab(ctx, &mnt)
node.state.PartTab = pt node.state.PartTab = pt
// XXX update "operational" if err != nil {
/* // keep mlink=nil on shutdown so that
// update .operational + notify those who was waiting for it // .operational does not change to y.
opready := c.updateOperational() node.mlink = mlink
c.node.StateMu.Unlock() }
opready() })
*/ if err != nil {
node.opMu.Unlock()
if err != nil { // might be command to shutdown
return err return err
} }
// XXX update .masterLink + notify waiters
wg := xsync.NewWorkGroup(ctx) wg := xsync.NewWorkGroup(ctx)
// receive and handle notifications from master // receive and handle notifications from master
wg.Go(func(ctx context.Context) error { wg.Go(func(ctx context.Context) error {
...@@ -279,7 +277,7 @@ func (node *_MasteredNode) recvMaster1(ctx context.Context, req neonet.Request) ...@@ -279,7 +277,7 @@ func (node *_MasteredNode) recvMaster1(ctx context.Context, req neonet.Request)
if δstate { if δstate {
δpt, err := node.recvδstate(ctx, req.Msg) δpt, err := node.recvδstate(ctx, req.Msg)
toRecvM1 := false toRecvM1 := false
if δpt && (node.flags & δPartTabPassThrough != 0) { if δpt && (node.rxmFlags & δPartTabPassThrough != 0) {
toRecvM1 = true toRecvM1 = true
} }
if !toRecvM1 { if !toRecvM1 {
...@@ -318,9 +316,8 @@ func (node *_MasteredNode) RecvM1() (neonet.Request, error) { ...@@ -318,9 +316,8 @@ func (node *_MasteredNode) RecvM1() (neonet.Request, error) {
func (node *_MasteredNode) recvδstate(ctx context.Context, msg proto.Msg) (δpt bool, err error) { func (node *_MasteredNode) recvδstate(ctx context.Context, msg proto.Msg) (δpt bool, err error) {
δpt = false δpt = false
node.opMu.Lock() // update .operational + notify those who was waiting for it
// XXX defer unlock ? node.updateOperational(func() {
switch msg := msg.(type) { switch msg := msg.(type) {
default: default:
node.opMu.Unlock() node.opMu.Unlock()
...@@ -348,30 +345,27 @@ func (node *_MasteredNode) recvδstate(ctx context.Context, msg proto.Msg) (δpt ...@@ -348,30 +345,27 @@ func (node *_MasteredNode) recvδstate(ctx context.Context, msg proto.Msg) (δpt
node.state.Code = msg.State node.state.Code = msg.State
traceClusterStateChanged(&node.state.Code) traceClusterStateChanged(&node.state.Code)
} }
})
// update .operational + notify those who was waiting for it
opready := node.updateOperational()
node.opMu.Unlock()
opready()
return δpt, err return δpt, err
} }
// updateOperational updates .operational from current state. // updateOperational calls δf under .opMu and updates .operational from current state.
// // it also notifies those who was waiting for it if operational state becomes ready.
// Must be called with .opMu lock held. func (node *_MasteredNode) updateOperational(δf func()) {
// var opready chan struct{}
// Returned sendReady func must be called by updateOperational caller after
// .node.StateMu lock is released - it will close current .opReady this way node.opMu.Lock()
// notifying .operational waiters. func() {
func (node *_MasteredNode) updateOperational() (sendReady func()) { defer node.opMu.Unlock()
operational := node.state.IsOperational() δf()
operational := (node.mlink != nil) && node.state.IsOperational()
//fmt.Printf("\nupdateOperatinal: %v\n", operational) //fmt.Printf("\nupdateOperatinal: %v\n", operational)
//fmt.Println(node.partTab) //fmt.Println(node.partTab)
//fmt.Println(node.nodeTab) //fmt.Println(node.nodeTab)
var opready chan struct{}
if operational != node.operational { if operational != node.operational {
node.operational = operational node.operational = operational
if operational { if operational {
...@@ -381,12 +375,12 @@ func (node *_MasteredNode) updateOperational() (sendReady func()) { ...@@ -381,12 +375,12 @@ func (node *_MasteredNode) updateOperational() (sendReady func()) {
} }
} }
return func() { }()
if opready != nil { if opready != nil {
//fmt.Println("updateOperational - notifying %v\n", opready) //fmt.Println("updateOperational - notifying %v\n", opready)
close(opready) close(opready)
} }
}
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment