Esempio n. 1
0
        /// <summary>
        /// Handover key if: 1. leave overlay 2. I'm AP while a join req happens.
        /// </summary>
        /// <param name="fSendLeaveFirst"></param>
        /// <returns></returns>
        public IEnumerator<ITask> HandoverKeys(bool fSendLeaveFirst)
        {
            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Handover Keys!");

            if (fSendLeaveFirst)
            {
                yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask(Leave));
            }

            // For each Resource stored at this Peer, handover StoredData
            List<string> storedKeys;
            if ((storedKeys = m_topology.Storage.StoredKeys) != null && storedKeys.Count > 0)
            {

                m_topology.Storage.RemoveExpired();

                Dictionary<ResourceId, List<StoreKindData>> nodes = new Dictionary<ResourceId, List<StoreKindData>>();

                Dictionary<ResourceId, Node> destinations = new Dictionary<ResourceId, Node>();

                foreach (string key in storedKeys)
                {
                    ResourceId res_id = new ResourceId(ReloadGlobals.HexToBytes(key));
                    Node currentNode = m_topology.routing_table.FindNextHopTo(new NodeId(res_id), true, fSendLeaveFirst);
                    if (currentNode == null || currentNode.Id == m_ReloadConfig.LocalNodeID)
                    {
                        //everything's fine, key still belongs to me
                        continue;
                    }
                    // REPLICATEST
                    // peer is no longer in the replica set for the resource
                    else if (m_topology.routing_table.Predecessors.Count > 2 && !res_id.ElementOfInterval(m_topology.routing_table.Predecessors[2], m_topology.LocalNode.Id, false))
                    {
                        m_topology.Storage.Remove(res_id.ToString());
                        m_topology.Replicas.Remove(res_id.ToString());
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("Data {0} no longer in range. Delete replica", res_id.ToString()));
                    }
                    else
                    {
                        if (!m_topology.Replicas.Contains(key))
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Handover Keys - will send store requests");
                            if (!nodes.ContainsKey(res_id))
                            {
                                nodes.Add(res_id, new List<StoreKindData>());
                                nodes[res_id].AddRange(m_topology.Storage.GetStoreKindData(key));

                                destinations.Add(res_id, currentNode);
                            }
                            else
                            {
                                nodes[res_id].AddRange(m_topology.Storage.GetStoreKindData(key));
                            }
                        }
                    }
                }

                ReloadDialog reloadDialog = null;
                ReloadMessage reloadSendMsg;
                List<StoreKindData> storeKindData;

                foreach (ResourceId res_id in nodes.Keys)
                {
                    Node node = destinations[res_id];
                    storeKindData = nodes[res_id];

                    List<SignerIdentity> signers = new List<SignerIdentity>();

                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "GOING TO STORE UNDER RES_ID: " + res_id);

                    foreach (StoreKindData skd in storeKindData)
                    {
                        foreach (StoredData sd in skd.Values)
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "STOREDATA: " + sd.Value.GetUsageValue.Report());

                            // add certificate
                            if (!signers.Contains(sd.Signature.Identity))
                                signers.Add(sd.Signature.Identity);
                        }
                    }

                    if (m_machine.ReloadConfig.State == ReloadConfig.RELOAD_State.Leave)
                    {
                        node = m_topology.routing_table.GetSuccessor(0);
                        reloadSendMsg = create_store_req(new Destination(node.Id), res_id, storeKindData, false);
                    }
                    else
                    {
                        reloadSendMsg = create_store_req(new Destination(res_id), storeKindData, false);
                    }

                    // get certificates for this data
                    List<GenericCertificate> certs = new List<GenericCertificate>();
                    certs.AddRange(m_ReloadConfig.AccessController.GetPKCs(signers));

                    // add certificates to fetch answer
                    reloadSendMsg.security_block.Certificates.AddRange(certs);

                    int RetransmissionTime = ReloadGlobals.RetransmissionTime + ReloadGlobals.MaxTimeToSendPacket;

                    int iRetrans = ReloadGlobals.MaxRetransmissions;

                    while (iRetrans >= 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit)
                    {
                        try
                        {
                            reloadDialog = new ReloadDialog(m_ReloadConfig, m_flm, node);

                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}",
                                reloadSendMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), node.Id, reloadSendMsg.TransactionID));

                            Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessage, ReloadMessageFilter, int>(reloadSendMsg, new ReloadMessageFilter(reloadSendMsg.TransactionID), RetransmissionTime, reloadDialog.Execute));
                        }
                        catch (Exception ex)
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Store: " + ex.Message);
                        }

                        yield return Arbiter.Receive(false, reloadDialog.Done, done => { });

                        if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null)
                            break;


                        /* If a response has not been received when the timer fires, the request
                           is retransmitted with the same transaction identifier. 
                        */
                        --iRetrans;
                    }

                    try
                    {
                        if (!reloadDialog.Error && reloadDialog.ReceivedMessage != null)
                        {
                            ReloadMessage reloadRcvMsg = reloadDialog.ReceivedMessage;

                            if (reloadRcvMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Store_Answer)
                            {
                                m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} <== {1} TransId={2:x16}", reloadRcvMsg.reload_message_body.RELOAD_MsgCode.ToString().PadRight(16, ' '), reloadRcvMsg.OriginatorID, reloadRcvMsg.TransactionID));

                                //StoreReqAns answ = (StoreReqAns)reloadRcvMsg.reload_message_body; --old
                                StoreAns answ = (StoreAns)reloadRcvMsg.reload_message_body; // --alex

                                if (answ != null)
                                {
                                    // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Delete Key {0}", res_id));
                                    // m_topology.StoredValues.Remove(StoredKey); --old

                                    // REPLICATEST
                                    // Keep stored data but mark it as replica
                                    if (!m_topology.Replicas.Contains(res_id.ToString()))
                                        m_topology.Replicas.Add(res_id.ToString());

                                    //m_topology.Storage.Remove(res_id.ToString());
                                }
                            }
                        }
                        else
                        {
                            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Store failed"));
                            m_statistics.IncTransmissionError();
                        }
                    }
                    catch (Exception ex)
                    {
                        m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "Send Store: " + ex.Message);
                    }
                }
            }

            // this code might be redundant to code in RoutingTable.Leave()

            //// check if there are replicas I should be responsible for
            //if (m_topology.routing_table.Predecessors.Count == 0)
            //{
            //    m_topology.Replicas.Clear();
            //}
            //else
            //{
            //    List<string> removeReplicas = new List<string>();
            //    foreach (string replica in m_topology.Replicas)
            //    {
            //        // Convert the Resource String in a ResourceId
            //        int NumberChars = replica.Length;
            //        byte[] bytes = new byte[NumberChars / 2];
            //        for (int i = 0; i < NumberChars; i += 2)
            //            bytes[i / 2] = Convert.ToByte(replica.Substring(i, 2), 16);
            //        ResourceId id = new ResourceId(bytes);

            //        if (id.ElementOfInterval(m_topology.routing_table.Predecessors[0], m_topology.LocalNode.Id, false))
            //        {
            //            m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("ResId: {0} is in interval [{1} - {2}]", id, m_topology.routing_table.Predecessors[0], m_topology.LocalNode.Id));
            //            removeReplicas.Add(replica);
            //        }
            //    }
            //    foreach (string removeRep in removeReplicas)
            //    {
            //        m_topology.Replicas.Remove(removeRep);
            //        Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_topology.routing_table.Successors[0], StoreReplicas));
            //        if(m_topology.routing_table.Successors.Count > 1)
            //            Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_topology.routing_table.Successors[1], StoreReplicas));
            //    }
            //}

            if (m_ReloadConfig.State == ReloadConfig.RELOAD_State.Leave)
                m_machine.SendCommand("Exit");

            if (fSendLeaveFirst)
                //this will reset neighbor tables
                m_topology.Leave();
        }
Esempio n. 2
0
        // REPLICATEST

        public void EvaluateReplicas()
        {
            List<String> ReplicasToRemove = new List<string>();

            foreach (String rep in m_topology.Replicas)
            {
                ResourceId id = new ResourceId(rep);

                if (m_topology.routing_table.Predecessors.Count > 0)
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("EvaluateReplicas: Is data {0} in interval {1} - {2}", rep, m_topology.routing_table.Predecessors[0], m_topology.LocalNode.Id));
                else
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("Nobody is left. All the data belong to me"));

                if (m_topology.routing_table.Predecessors.Count > 0 && id.ElementOfInterval(m_topology.routing_table.Predecessors[0], m_topology.LocalNode.Id, false))
                {
                    ReplicasToRemove.Add(rep);
                    m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("EvaluateReplicas: I'm now responsible for data {0}", rep));

                    if (m_topology.routing_table.Successors.Count > 0)
                        Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_topology.routing_table.Successors[0], StoreReplicas));
                    if (m_topology.routing_table.Successors.Count > 1)
                        Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<NodeId>(m_topology.routing_table.Successors[1], StoreReplicas));
                }
            }

            foreach (String rep in ReplicasToRemove)
            {
                m_topology.Replicas.Remove(rep);
            }
        }