Example #1
0
 /// <summary>
 /// Creates the routing mechanism. Make sure to set the Max* fields.
 /// </summary>
 /// <param name="tcsResponses">The current task responses that are running.</param>
 /// <param name="tcsRoutingResponse">The response task from this routing request.</param>
 /// <param name="peerFilters"></param>
 public RoutingMechanism(VolatileReferenceArray<TaskCompletionSource<Message.Message>> tcsResponses,
     TcsRouting tcsRoutingResponse, ICollection<IPeerFilter> peerFilters)
 {
     TcsResponses = tcsResponses;
     TcsRoutingResponse = tcsRoutingResponse;
     _peerFilters = peerFilters;
 }
Example #2
0
 /// <summary>
 /// Creates the routing mechanism. Make sure to set the Max* fields.
 /// </summary>
 /// <param name="tcsResponses">The current task responses that are running.</param>
 /// <param name="tcsRoutingResponse">The response task from this routing request.</param>
 /// <param name="peerFilters"></param>
 public RoutingMechanism(VolatileReferenceArray <TaskCompletionSource <Message.Message> > tcsResponses,
                         TcsRouting tcsRoutingResponse, ICollection <IPeerFilter> peerFilters)
 {
     TcsResponses       = tcsResponses;
     TcsRoutingResponse = tcsRoutingResponse;
     _peerFilters       = peerFilters;
 }
Example #3
0
 public RoutingMechanism CreateRoutingMechanism(TcsRouting tcsRouting)
 {
     var tcsResponses = new TaskCompletionSource<Message.Message>[Parallel];
     var tcsResponseArray = new VolatileReferenceArray<TaskCompletionSource<Message.Message>>(tcsResponses);
     var routingMechanism = new RoutingMechanism(tcsResponseArray, tcsRouting, PeerFilters)
     {
         MaxDirectHits = MaxDirectHits,
         MaxFailures = MaxFailures,
         MaxNoNewInfo = MaxNoNewInfo,
         MaxSucess = MaxSuccess
     };
     return routingMechanism;
 }
Example #4
0
        public RoutingMechanism CreateRoutingMechanism(TcsRouting tcsRouting)
        {
            var tcsResponses     = new TaskCompletionSource <Message.Message> [Parallel];
            var tcsResponseArray = new VolatileReferenceArray <TaskCompletionSource <Message.Message> >(tcsResponses);
            var routingMechanism = new RoutingMechanism(tcsResponseArray, tcsRouting, PeerFilters)
            {
                MaxDirectHits = MaxDirectHits,
                MaxFailures   = MaxFailures,
                MaxNoNewInfo  = MaxNoNewInfo,
                MaxSucess     = MaxSuccess
            };

            return(routingMechanism);
        }
Example #5
0
        /// <summary>
        /// Creates a TcsForkJoin object.
        /// </summary>
        /// <param name="nrFinishFuturesSuccess">The number of tasks expected to succeed.</param>
        /// <param name="cancelTasksOnFinish">Whether the remaining tasks should be cancelled.
        /// For Get() it makes sense, for Store() it dose not.</param>
        /// <param name="forks">The tasks that can also be modified outside this class.
        /// If a task is finished, the the task in that array will be set to null.
        /// A task may be initially null, which is considered a failure.</param>
        public TcsForkJoin(int nrFinishFuturesSuccess, bool cancelTasksOnFinish, VolatileReferenceArray <TTask> forks)
        {
            _nrFinishTaskSuccess = nrFinishFuturesSuccess;
            _cancelTasksOnFinish = cancelTasksOnFinish;
            _forks = forks;

            // the task array may have null entries, so count first
            _nrTasks = forks.Length;
            if (_nrTasks <= 0)
            {
                // "failed"
                SetException(new TaskFailedException("We have no tasks: " + _nrTasks));
            }
            else
            {
                Join();
            }
            // TODO self needed?
        }
Example #6
0
        private void RoutingRec(RoutingBuilder routingBuilder, RoutingMechanism routingMechanism,
                                Message.Message.MessageType type, ChannelCreator channelCreator)
        {
            var randomSearch = routingBuilder.LocationKey == null;
            var active       = 0;

            for (var i = 0; i < routingMechanism.Parallel; i++)
            {
                if (routingMechanism.GetTcsResponse(i) == null &&
                    !routingMechanism.IsStopCreatingNewFutures)
                {
                    PeerAddress next;
                    if (randomSearch)
                    {
                        next = routingMechanism.PollRandomInQueueToAsk(_rnd);
                    }
                    else
                    {
                        next = routingMechanism.PollFirstInQueueToAsk();
                    }
                    if (next != null)
                    {
                        routingMechanism.AddToAlreadyAsked(next);
                        active++;
                        // If we search for a random peer, then the peer should
                        // return the address farest away.
                        var locationKey2 = randomSearch
                            ? next.PeerId.Xor(Number160.MaxValue)
                            : routingBuilder.LocationKey;
                        routingBuilder.LocationKey = locationKey2;

                        // routing is per default UDP, don't show warning if the other TCP/UDP is used
                        // TODO find .NET-specific way to show sanity check warning

                        routingMechanism.SetTcsResponse(i,
                                                        _neighbors.CloseNeighborsTcs(next, routingBuilder.SearchValues(), type, channelCreator,
                                                                                     routingBuilder));
                        Logger.Debug("Get close neighbours: {0} on {1}.", next, i);
                    }
                }
                else if (routingMechanism.GetTcsResponse(i) != null)
                {
                    Logger.Debug("Activity on {0}.", i);
                    active++;
                }
            }

            if (active == 0)
            {
                Logger.Debug("No activity, closing.");
                routingMechanism.SetNeighbors(routingBuilder);
                routingMechanism.Cancel();
                return;
            }

            // .NET-specific: // TODO move to TcsForkJoin as separate c'tor?
            var extractedTasks = new Task <Message.Message> [routingMechanism.TcsResponses.Length];

            for (int i = 0; i < routingMechanism.TcsResponses.Length; i++)
            {
                extractedTasks[i] = routingMechanism.GetTcsResponse(i) != null?routingMechanism.GetTcsResponse(i).Task : null;
            }
            var volatileArray = new VolatileReferenceArray <Task <Message.Message> >(extractedTasks);

            bool last        = active == 1;
            var  tcsForkJoin = new TcsForkJoin <Task <Message.Message> >(1, false, volatileArray);

            tcsForkJoin.Task.ContinueWith(tfj =>
            {
                bool finished;
                if (!tfj.IsFaulted)
                {
                    var lastResponse = tcsForkJoin.Last.Result;
                    var remotePeer   = lastResponse.Sender;
                    routingMechanism.AddPotentialHits(remotePeer);
                    var newNeighbors = lastResponse.NeighborsSet(0).Neighbors;

                    var resultSize    = lastResponse.IntAt(0);
                    var keyDigest     = lastResponse.Key(0);
                    var contentDigest = lastResponse.Key(1);
                    var digestBean    = new DigestInfo(keyDigest, contentDigest, resultSize);
                    Logger.Debug("Peer ({0}) {1} reported {2} in message {3}.", (digestBean.Size > 0 ? "direct" : "none"), remotePeer, newNeighbors.Count, lastResponse);
                    finished = routingMechanism.EvaluateSuccess(remotePeer, digestBean, newNeighbors, last,
                                                                routingBuilder.LocationKey);
                    Logger.Debug("Routing finished {0} / {1}.", finished, routingMechanism.IsStopCreatingNewFutures);
                }
                else
                {
                    // if it failed but the failed is the closest one, it is good to try again,
                    // since the peer might just be busy
                    Logger.Debug("Routing error {0}.", tfj.Exception);
                    finished = routingMechanism.EvaluateFailed();
                    routingMechanism.IsStopCreatingNewFutures = finished;
                }

                if (finished)
                {
                    Logger.Debug("Routing finished. Direct hits: {0}. Potential hits: {1}.", routingMechanism.DirectHits.Count, routingMechanism.PotentialHits.Count);
                    routingMechanism.SetNeighbors(routingBuilder);
                    routingMechanism.Cancel();
                    // stop all operations, as we are finished, no need to go further
                }
                else
                {
                    RoutingRec(routingBuilder, routingMechanism, type, channelCreator);
                }
            });
        }
Example #7
0
 /// <summary>
 /// Facade if we expect everythin to return successfully.
 /// </summary>
 /// <param name="forks">The tasks that can also be modified outside this class.
 /// If a task is finished, the the task in that array will be set to null.
 /// A task may be initially null, which is considered a failure.</param>
 public TcsForkJoin(VolatileReferenceArray <TTask> forks)
     : this(forks.Length, false, forks)
 {
 }
        private void RoutingRec(RoutingBuilder routingBuilder, RoutingMechanism routingMechanism,
            Message.Message.MessageType type, ChannelCreator channelCreator)
        {
            var randomSearch = routingBuilder.LocationKey == null;
            var active = 0;
            for (var i = 0; i < routingMechanism.Parallel; i++)
            {
                if (routingMechanism.GetTcsResponse(i) == null
                    && !routingMechanism.IsStopCreatingNewFutures)
                {
                    PeerAddress next;
                    if (randomSearch)
                    {
                        next = routingMechanism.PollRandomInQueueToAsk(_rnd);
                    }
                    else
                    {
                        next = routingMechanism.PollFirstInQueueToAsk();
                    }
                    if (next != null)
                    {
                        routingMechanism.AddToAlreadyAsked(next);
                        active++;
                        // If we search for a random peer, then the peer should
                        // return the address farest away.
                        var locationKey2 = randomSearch
                            ? next.PeerId.Xor(Number160.MaxValue)
                            : routingBuilder.LocationKey;
                        routingBuilder.LocationKey = locationKey2;

                        // routing is per default UDP, don't show warning if the other TCP/UDP is used
                        // TODO find .NET-specific way to show sanity check warning

                        routingMechanism.SetTcsResponse(i,
                            _neighbors.CloseNeighborsTcs(next, routingBuilder.SearchValues(), type, channelCreator,
                                routingBuilder));
                        Logger.Debug("Get close neighbours: {0} on {1}.", next, i);
                    }
                }
                else if (routingMechanism.GetTcsResponse(i) != null)
                {
                    Logger.Debug("Activity on {0}.", i);
                    active++;
                }
            }

            if (active == 0)
            {
                Logger.Debug("No activity, closing.");
                routingMechanism.SetNeighbors(routingBuilder);
                routingMechanism.Cancel();
                return;
            }

            // .NET-specific: // TODO move to TcsForkJoin as separate c'tor?
            var extractedTasks = new Task<Message.Message>[routingMechanism.TcsResponses.Length];
            for (int i = 0; i < routingMechanism.TcsResponses.Length; i++)
            {
                extractedTasks[i] = routingMechanism.GetTcsResponse(i) != null ? routingMechanism.GetTcsResponse(i).Task : null;
            }
            var volatileArray = new VolatileReferenceArray<Task<Message.Message>>(extractedTasks);

            bool last = active == 1;
            var tcsForkJoin = new TcsForkJoin<Task<Message.Message>>(1, false, volatileArray);
            tcsForkJoin.Task.ContinueWith(tfj =>
            {
                bool finished;
                if (!tfj.IsFaulted)
                {
                    var lastResponse = tcsForkJoin.Last.Result;
                    var remotePeer = lastResponse.Sender;
                    routingMechanism.AddPotentialHits(remotePeer);
                    var newNeighbors = lastResponse.NeighborsSet(0).Neighbors;

                    var resultSize = lastResponse.IntAt(0);
                    var keyDigest = lastResponse.Key(0);
                    var contentDigest = lastResponse.Key(1);
                    var digestBean = new DigestInfo(keyDigest, contentDigest, resultSize);
                    Logger.Debug("Peer ({0}) {1} reported {2} in message {3}.", (digestBean.Size > 0 ? "direct" : "none"), remotePeer, newNeighbors.Count, lastResponse);
                    finished = routingMechanism.EvaluateSuccess(remotePeer, digestBean, newNeighbors, last,
                        routingBuilder.LocationKey);
                    Logger.Debug("Routing finished {0} / {1}.", finished, routingMechanism.IsStopCreatingNewFutures);
                }
                else
                {
                    // if it failed but the failed is the closest one, it is good to try again,
                    // since the peer might just be busy
                    Logger.Debug("Routing error {0}.", tfj.Exception);
                    finished = routingMechanism.EvaluateFailed();
                    routingMechanism.IsStopCreatingNewFutures = finished;
                }

                if (finished)
                {
                    Logger.Debug("Routing finished. Direct hits: {0}. Potential hits: {1}.", routingMechanism.DirectHits.Count, routingMechanism.PotentialHits.Count);
                    routingMechanism.SetNeighbors(routingBuilder);
                    routingMechanism.Cancel();
                    // stop all operations, as we are finished, no need to go further
                }
                else
                {
                    RoutingRec(routingBuilder, routingMechanism, type, channelCreator);
                }
            });
        }