Пример #1
0
// Unregister removes the given claim from a given global name.
// Unregistration will only occur if the current registrant matches the
// address passed in. It is not an error for it not to match; the call will
// simply be ignored.
//
// On a given node, only one Address can have a claim on a
// name. If you wish to supercede a claim with a new address, you can
// simply register the new claim, and it will overwrite the previous one.
func (r *registry) Unregister(name string, addr Address) {
	if !addr.GetID().canBeGloballyRegistered() {
		return
	}

	// at the moment, only mailboxID can pass the check above
	r.Send(internal.UnregisterName{
		internal.IntNodeID(r.thisNode),
		name,
		internal.IntMailboxID(addr.GetID().(mailboxID)),
	})
}
Пример #2
0
// Register claims the given global name in the registry.
//
// This does not happen synchronously, as there seems to be no reason
// for the caller to synchronously wait for this.
//
// A registered mailbox should stand ready to receive MultipleClaim
// messages from the cluster.
func (r *registry) Register(name string, addr Address) error {
	if !addr.GetID().canBeGloballyRegistered() {
		return ErrCantGloballyRegister
	}

	// only mailboxID can pass the canBeGloballyRegistered test above
	r.Send(internal.RegisterName{
		internal.IntNodeID(r.thisNode),
		name,
		internal.IntMailboxID(addr.GetID().(mailboxID)),
	})
	return nil
}
Пример #3
0
func (ic *incomingConnection) clusterHandshake() error {
	if ic.nodeListener.failOnClusterHandshake {
		ic.Trace("In cluster handshake, and told to fail it")
		ic.terminate()
		return errors.New("cluster handshake simulating failure")
	}
	var clientHandshake internal.ClusterHandshake
	err := ic.input.Decode(&clientHandshake)
	if err != nil {
		return err
	}

	myNodeID := NodeID(clientHandshake.MyNodeID)
	yourNodeID := NodeID(clientHandshake.YourNodeID)

	if clientHandshake.ClusterVersion != clusterVersion {
		ic.Warn("Remote node %d claimed unknown cluster version %v, proceding in the hope that this will all just work out somehow...", clientHandshake.MyNodeID, clientHandshake.ClusterVersion)
	}
	if yourNodeID != ic.nodeListener.connectionServer.Cluster.ThisNode.ID {
		ic.Warn("The remote node (claiming ID #d) thinks I'm node #d, but I think I'm node %d. These two nodes can not communicate properly. Standing by, hoping a new node definition will resolve this shortly...", clientHandshake.MyNodeID, clientHandshake.YourNodeID, ic.nodeListener.connectionServer.Cluster.ThisNode.ID)
	}

	clientNodeDefinition, exists := ic.nodeListener.connectionServer.Cluster.Nodes[myNodeID]
	if !exists {
		ic.Error("Connecting node claims to have ID %d, but I don't have a definition for that node.", clientHandshake.MyNodeID)
	}
	ic.client = clientNodeDefinition

	myHandshake := internal.ClusterHandshake{
		ClusterVersion: clusterVersion,
		MyNodeID:       internal.IntNodeID(ic.nodeListener.connectionServer.Cluster.ThisNode.ID),
		YourNodeID:     internal.IntNodeID(clientHandshake.MyNodeID),
	}
	ic.output.Encode(myHandshake)

	ic.input = gob.NewDecoder(ic.tls)

	return nil
}
Пример #4
0
func (nc *nodeConnection) clusterHandshake() error {
	if nc.failOnClusterHandshake {
		nc.tls.Close()
		nc.Trace("Failing on cluster handshake, as instructed")
		return errors.New("failing on cluster handshake, as instructed")
	}
	handshake := internal.ClusterHandshake{
		ClusterVersion: clusterVersion,
		MyNodeID:       internal.IntNodeID(nc.source.ID),
		YourNodeID:     internal.IntNodeID(nc.dest.ID),
	}

	nc.output.Encode(handshake)

	var serverHandshake internal.ClusterHandshake
	err := nc.input.Decode(&serverHandshake)
	if err != nil {
		return err
	}

	myNodeID := NodeID(serverHandshake.MyNodeID)
	yourNodeID := NodeID(serverHandshake.YourNodeID)

	if serverHandshake.ClusterVersion != clusterVersion {
		connections.Warn("Remote node id %v claimed unknown cluster version %v, proceeding in the hope that this will all just work out somehow...", nc.dest.ID, serverHandshake.ClusterVersion)
	}
	if myNodeID != nc.dest.ID {
		connections.Warn("The node I thought was #%v is claiming to be #%v instead. These two nodes can not communicate properly. Standing by, hoping a new node definition will resolve this shortly....", nc.dest.ID, serverHandshake.MyNodeID)
	}
	if yourNodeID != nc.source.ID {
		connections.Warn("The node #%v thinks I'm node #%v, but I think I'm node #%v. These two nodes can not communicate properly. Standing by, hoping a new node definition will resolve this shortly...", nc.dest.ID, serverHandshake.YourNodeID, nc.source.ID)
	}

	nc.input = gob.NewDecoder(nc.tls)

	return nil
}
Пример #5
0
// This registers a node's registry mailbox. This should only happen once
// per connection to that node. Even if it is the same as last time, it
// triggers the synchronization process.
func (r *registry) registerNodeRegistryMailbox(node NodeID, addr Address) {
	r.nodeRegistries[node] = addr

	// send initial synchronization
	claims := map[string]internal.IntMailboxID{}
	anc := internal.AllNodeClaims{internal.IntNodeID(r.thisNode), claims}

	// Copy the claims. This has to be a fresh copy to make sure we don't
	// lose anything to race conditions. If this becomes a performance
	// bottleneck, we could try to do a serialization immediately in this
	// step, since this gets copied and then serialized anyhow.
	for name, mID := range r.nodeClaims[r.thisNode] {
		claims[name] = internal.IntMailboxID(mID)
	}

	addr.Send(anc)
}