Exemplo n.º 1
0
// This function is responsible for communicating with instance processing.
func (r *Replica) dispatch(msg message.Message) {
	replicaId := msg.Replica()
	instanceId := msg.Instance()

	r.updateMaxInstanceNum(replicaId, instanceId)

	v1Log.Infof("Replica[%v]: recv message[%s], from Replica[%v]\n",
		r.Id, msg.String(), msg.Sender())
	if glog.V(0) {
		printDependencies(msg)
	}

	if instanceId <= conflictNotFound {
		panic("")
	}

	if r.InstanceMatrix[replicaId][instanceId] == nil {
		r.InstanceMatrix[replicaId][instanceId] = NewInstance(r, replicaId, instanceId)
		if p, ok := msg.(*message.Propose); ok {
			// send back a signal for this successfully creation
			close(p.Created)
		}
	}

	i := r.InstanceMatrix[replicaId][instanceId]
	i.touch() // update last touched timestamp

	v1Log.Infof("Replica[%v]: instance[%v][%v] status before = %v, ballot = [%v]\n",
		r.Id, replicaId, instanceId, i.StatusString(), i.ballot.String())
	v2Log.Infof("dependencies before: %v\n", i.Dependencies())

	var action uint8
	var rep message.Message

	switch i.status {
	case nilStatus:
		action, rep = i.nilStatusProcess(msg)
	case preAccepted:
		action, rep = i.preAcceptedProcess(msg)
	case accepted:
		action, rep = i.acceptedProcess(msg)
	case committed:
		action, rep = i.committedProcess(msg)
	case preparing:
		action, rep = i.preparingProcess(msg)
	default:
		panic("")
	}

	v2Log.Infof("dependencies after: %v\n", i.Dependencies())
	if action == noAction {
		v1Log.Infof("Replica[%v]: instance[%v][%v] status after = %v, ballot = [%v]\n\n\n",
			r.Id, replicaId, instanceId, i.StatusString(), i.ballot.String())
	} else {
		v1Log.Infof("Replica[%v]: instance[%v][%v] status after = %v, ballot = [%v]\n",
			r.Id, replicaId, instanceId, i.StatusString(), i.ballot.String())
	}

	if r.enablePersistent {
		r.StoreSingleInstance(i)
	}

	switch action {
	case noAction:
		return
	case replyAction:
		v1Log.Infof("Replica[%v]: send message[%s], to Replica[%v]\n\n\n",
			r.Id, rep.String(), msg.Sender())
		r.Transporter.Send(msg.Sender(), rep) // send back to the sender of the message
	case fastQuorumAction:
		v1Log.Infof("Replica[%v]: send message[%s], to FastQuorum\n\n\n",
			r.Id, rep.String())
		r.Transporter.MulticastFastquorum(rep)
	case broadcastAction:
		v1Log.Infof("Replica[%v]: send message[%s], to Everyone\n\n\n",
			r.Id, rep.String())
		r.Transporter.Broadcast(rep)
	default:
		panic("")
	}
}