gopkg.in/dedis/onet.v2@v2.0.0-20181115163211-c8f3724038a7/simul/manage/close_all.go (about) 1 package manage 2 3 import ( 4 "time" 5 6 "gopkg.in/dedis/onet.v2" 7 "gopkg.in/dedis/onet.v2/log" 8 "gopkg.in/dedis/onet.v2/network" 9 ) 10 11 /* 12 Protocol used to close all connections, starting from the leaf-nodes. 13 It first sends down a message `PrepareClose` through the tree, then 14 from the leaf-nodes a `Close`-message up to the root. Every node receiving 15 the `Close`-message will shut down all network communications. 16 17 The protocol waits for the `Close`-message to arrive at the root. 18 */ 19 20 func init() { 21 network.RegisterMessage(PrepareClose{}) 22 network.RegisterMessage(Close{}) 23 onet.GlobalProtocolRegister("CloseAll", NewCloseAll) 24 } 25 26 // ProtocolCloseAll is the structure used to hold the Done-channel 27 type ProtocolCloseAll struct { 28 *onet.TreeNodeInstance 29 // Done receives a 'true' once the protocol is done. 30 Done chan bool 31 } 32 33 // PrepareClose is sent down the tree until the nodes 34 type PrepareClose struct{} 35 36 // PrepareCloseMsg is the wrapper for the PrepareClose message 37 type PrepareCloseMsg struct { 38 *onet.TreeNode 39 PrepareClose 40 } 41 42 // Close is sent to the parent just before the node shuts down 43 type Close struct{} 44 45 // CloseMsg is the wrapper for the Close message 46 type CloseMsg struct { 47 *onet.TreeNode 48 Close 49 } 50 51 // NewCloseAll will create a new protocol 52 func NewCloseAll(n *onet.TreeNodeInstance) (onet.ProtocolInstance, error) { 53 p := &ProtocolCloseAll{TreeNodeInstance: n} 54 p.Done = make(chan bool, 1) 55 if err := p.RegisterHandler(p.FuncPrepareClose); err != nil { 56 return nil, err 57 } 58 if err := p.RegisterHandler(p.FuncClose); err != nil { 59 return nil, err 60 } 61 return p, nil 62 } 63 64 // Start the protocol and waits for the `Close`-message to arrive back at 65 // the root-node. 66 func (p *ProtocolCloseAll) Start() error { 67 // Send an empty message 68 p.FuncPrepareClose(PrepareCloseMsg{TreeNode: p.TreeNode()}) 69 // Wait till the end 70 <-p.Done 71 return nil 72 } 73 74 // FuncPrepareClose sends a `PrepareClose`-message down the tree. 75 func (p *ProtocolCloseAll) FuncPrepareClose(pc PrepareCloseMsg) error { 76 log.Lvl3(pc.ServerIdentity.Address, "sent PrepClose to", p.ServerIdentity().Address) 77 if !p.IsLeaf() { 78 for _, c := range p.Children() { 79 err := p.SendTo(c, &PrepareClose{}) 80 log.Lvl3(p.ServerIdentity().Address, "sends to", c.ServerIdentity.Address, "(err=", err, ")") 81 } 82 } else { 83 p.FuncClose(nil) 84 } 85 return nil 86 } 87 88 // FuncClose is called from the leafs to the parents and up the tree. Everybody 89 // receiving all `Close`-messages from all children will close down all 90 // network communication. 91 func (p *ProtocolCloseAll) FuncClose(c []CloseMsg) error { 92 if !p.IsRoot() { 93 log.Lvl3("Sending closeall from", p.ServerIdentity().Address, 94 "to", p.Parent().ServerIdentity.Address) 95 if err := p.SendTo(p.Parent(), &Close{}); err != nil { 96 log.Error(p.Info(), "couldn't send 'close' tp parent", 97 p.Parent(), err) 98 } 99 } 100 time.Sleep(time.Second) 101 log.Lvl3("Closing host", p.ServerIdentity().Address) 102 err := p.TreeNodeInstance.CloseHost() 103 if err != nil { 104 log.Error("Couldn't close:", err) 105 } 106 if p.IsRoot() { 107 log.Lvl2("Root received Close") 108 p.Done <- true 109 } 110 p.TreeNodeInstance.Done() 111 return nil 112 }