// 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)), }) }
// 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 }
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 }
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 }
// 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) }