Пример #1
0
func (fss *FsService) sendToReplicaNode(resolv *cluster.ResolveResult, req_cb func(node *cluster.Node) *comm.Message) chan os.Error {
	toSyncCount := resolv.Count() - 1 // minus one for the master
	var syncError os.Error = nil
	myNodeId := fss.cluster.MyNode.Id
	errChan := make(chan os.Error, 1) // channel used to return data to the messageor
	c := make(chan bool, toSyncCount) // channel used to wait for all replicas

	if toSyncCount > 0 {
		go func() {
			for i := 0; i < resolv.Count(); i++ {
				node := resolv.Get(i)

				if node.Status == cluster.Status_Online && node.Id != myNodeId {
					// get the new message
					req := req_cb(node)

					req.Timeout = 1000 // TODO: Config
					req.OnResponse = func(message *comm.Message) {
						log.Debug("%d: FSS: Received acknowledge message for message %s\n", fss.cluster.MyNode.Id, req)
						c <- true
					}
					req.OnTimeout = func(last bool) (retry bool, handled bool) {
						// TODO: Retry it!
						syncError = comm.ErrorTimeout
						log.Error("%d: FSS: Couldn't send message to replicate node %s because of a timeout for message %s\n", fss.cluster.MyNode.Id, node, req)
						c <- true

						return true, false
					}
					req.OnError = func(message *comm.Message, syncError os.Error) {
						log.Error("%d: FSS: Received an error while sending to replica %s for message %s: %d %s\n", fss.cluster.MyNode.Id, req, node, syncError)
						c <- true
					}

					fss.comm.SendNode(node, req)
				}
			}

			// wait for nodes to sync the handoff
			for i := 0; i < toSyncCount; i++ {
				<-c
			}

			errChan <- syncError
		}()
	} else {
		errChan <- nil
	}

	return errChan
}