Пример #1
0
        public void Queue(QueueGroupKey queueGroupKey)
        {
            lock (queueGroupKeyToExecutionTimeDict)
            {
                QueueGroup queueGroup = DictionaryExtension.ValueOrDefault(queueGroupKeyToExecutionTimeDict, queueGroupKey);
                if (queueGroup != null)
                {
                    // Runnable already pending with given QueueGroupKey
                    return;
                }
                queueGroup = new QueueGroup(queueGroupKey);

                queueGroupKeyToExecutionTimeDict.Add(queueGroupKey, queueGroup);
                bool queueGroupAdded = false;

                // Insert the QueueGroup at the right position of pending QueueGroups
                // At index 0 is the latest of all, at max-index the next triggering QueueGroup
                for (int a = 0, size = pendingQueueGroups.Count; a < size; a++)
                {
                    QueueGroup pendingQueueGroup = pendingQueueGroups[a];
                    if (queueGroup.ExecutionTime >= pendingQueueGroup.ExecutionTime)
                    {
                        // If new QueueGroup executes AFTER or EQUAL TO the current investigated QueueGroup,
                        // insert the new QueueGroup BEFORE in the list
                        pendingQueueGroups.Insert(a, queueGroup);
                        queueGroupAdded = true;
                        break;
                    }
                }
                if (!queueGroupAdded)
                {
                    pendingQueueGroups.Add(queueGroup);
                }
            }
        }
Пример #2
0
 public NextQueue GetQueue(IHttpContext context)
 {
     if (Type == ThreadQueueType.Single)
     {
         return(QueueGroup.Queues[0]);
     }
     else if (Type == ThreadQueueType.Multiple)
     {
         return(QueueGroup.Next());
     }
     else if (Type == ThreadQueueType.DataUnique)
     {
         string value = null;
         if (UniqueName != null)
         {
             context.Data.TryGetString(UniqueName, out value);
         }
         if (value == null)
         {
             value = context.Request.Url;
         }
         int index = System.Math.Abs(value.GetHashCode() % mUniqueQueueGroup.Queues.Count);
         return(mUniqueQueueGroup.Queues[index]);
     }
     return(QueueGroup.Next());
 }
Пример #3
0
        /// <summary>Find the next task that should be executed, based on priorities and fairness and the like.</summary>
        /// <param name="targetTask">The found task, or null if none was found.</param>
        /// <param name="queueForTargetTask">
        /// The scheduler associated with the found task.  Due to security checks inside of TPL,
        /// this scheduler needs to be used to execute that task.
        /// </param>
        void FindNextTaskNeedsLock(out Task targetTask, out QueuedTaskSchedulerQueue queueForTargetTask)
        {
            targetTask         = null;
            queueForTargetTask = null;

            // Look through each of our queue groups in sorted order.
            // This ordering is based on the priority of the queues.
            foreach (var queueGroup in _queueGroups)
            {
                QueueGroup queues = queueGroup.Value;

                // Within each group, iterate through the queues in a round-robin
                // fashion.  Every time we iterate again and successfully find a task,
                // we'll start in the next location in the group.
                foreach (int i in queues.CreateSearchOrder())
                {
                    queueForTargetTask = queues[i];
                    Queue <Task> items = queueForTargetTask._workItems;
                    if (items.Count > 0)
                    {
                        targetTask = items.Dequeue();
                        if (queueForTargetTask._disposed && items.Count == 0)
                        {
                            RemoveQueueNeedsLock(queueForTargetTask);
                        }
                        queues.NextQueueIndex = (queues.NextQueueIndex + 1) % queueGroup.Value.Count;
                        return;
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        ///     Flushes all entities from the in queue into the matchmaker.
        /// </summary>
        /// <returns>The groups inserted into the queue.</returns>
        private IEnumerable <QueueGroup> FlushInQueue()
        {
            Queue <QueueGroup> toInform = new Queue <QueueGroup>();

            lock (inQueue)
            {
                while (inQueue.Count > 0)
                {
                    QueueGroup queueGroup = inQueue.Dequeue();

                    //Copy suitability metrics into the other entities
                    foreach (Match match in queueGroup.matches)
                    {
                        match.other.matches.AddLast(new Match {
                            other = queueGroup, value = match.value
                        });
                    }

                    queue.AddLast(queueGroup);

                    toInform.Enqueue(queueGroup);
                }
            }

            return(toInform);
        }
Пример #5
0
        public void Queue <T>(QueueGroupKey <T> queueGroupKey, IEnumerable <T> items)
        {
            lock (queueGroupKeyToExecutionTimeDict)
            {
                QueueGroup queueGroup = DictionaryExtension.ValueOrDefault(queueGroupKeyToExecutionTimeDict, queueGroupKey);
                if (queueGroup != null)
                {
                    // Runnable already pending with given QueueGroupKey
                    IList queue2 = queueGroup.Queue;
                    foreach (T item in items)
                    {
                        queue2.Add(item);
                    }
                    return;
                }
                queueGroup = new QueueGroup(queueGroupKey, new List <T>());
                queueGroupKeyToExecutionTimeDict.Add(queueGroupKey, queueGroup);

                IList queue = queueGroup.Queue;
                foreach (T item in items)
                {
                    queue.Add(item);
                }
                QueueIntern <T>(queueGroup);
            }
        }
Пример #6
0
        /// <summary>
        ///     Flushes all the entities in the out queue from the matchmaker.
        /// </summary>
        /// <returns>The groups removed from the queue.</returns>
        private IEnumerable <QueueGroup> FlushOutQueue()
        {
            Queue <QueueGroup> toInform = new Queue <QueueGroup>();

            lock (outQueue)
            {
                while (outQueue.Count > 0)
                {
                    RankingMatchmakerQueueTask <T> task = outQueue.Dequeue();

                    //Get group and check it exists
                    QueueGroup queueGroup = queue.FirstOrDefault((g) => g.task == task);
                    if (queueGroup != null)
                    {
                        //Remove the group
                        queue.Remove(queueGroup);

                        //Remove all matches it had so we don't consider it in matchmaking
                        foreach (QueueGroup other in queue)
                        {
                            other.matches.Remove(new Match {
                                other = queueGroup
                            });
                        }

                        //If removed, inform it that it was cancelled
                        toInform.Enqueue(queueGroup);
                    }
                }
            }

            return(toInform);
        }
Пример #7
0
        /// <summary>Removes a scheduler from the group.</summary>
        /// <param name="queue">The scheduler to be removed.</param>
        private void RemoveQueue_NeedsLock(QueuedTaskSchedulerQueue queue)
        {
            QueueGroup group = this._queueGroups[queue._priority];
            int        index = group.IndexOf(queue);

            if (group.NextQueueIndex >= index)
            {
                group.NextQueueIndex--;
            }
            group.RemoveAt(index);
        }
Пример #8
0
        /// <summary>
        ///     Calculates and adds matches to the given group.
        /// </summary>
        /// <param name="group">The group to calculate for.</param>
        /// <param name="groups">The groups to calculate against.</param>
        /// <param name="context">The context for the matchmaker.</param>
        private void AddMatchesToQueueGroup(QueueGroup group, IEnumerable <QueueGroup> groups, MatchRankingContext <T> context)
        {
            foreach (QueueGroup other in groups)
            {
                float outerAcc = 0;
                bool  failed   = false;
                foreach (T entity in group.task.Entities)
                {
                    float acc = 0;
                    foreach (T otherEntity in other.task.Entities)
                    {
                        float value = GetSuitabilityMetric(entity, otherEntity, context);

                        //Check individual discard threshold, if not enough ignore the group
                        if (value < DiscardThreshold)
                        {
                            failed = true;
                            break;
                        }

                        acc += value;
                    }

                    //If we've already failed then just skip the reset
                    if (failed)
                    {
                        break;
                    }

                    outerAcc += acc / other.task.Entities.Count;
                }

                //Already failed, don't add match
                if (failed)
                {
                    continue;
                }

                outerAcc /= group.task.Entities.Count;

                //If a good enough match then add to our list of posible matches
                if (outerAcc >= GroupDiscardThreshold)
                {
                    group.matches.AddLast(new Match {
                        other = other, value = outerAcc
                    });
                }
            }
        }
Пример #9
0
        /// <summary>Creates and activates a new scheduling queue for this scheduler.</summary>
        /// <param name="priority">The priority level for the new queue.</param>
        /// <returns>The newly created and activated queue at the specified priority.</returns>
        public TaskScheduler ActivateNewQueue(int priority)
        {
            QueuedTaskSchedulerQueue item = new QueuedTaskSchedulerQueue(priority, this);

            lock (this._queueGroups)
            {
                QueueGroup group;
                if (!this._queueGroups.TryGetValue(priority, out group))
                {
                    group = new QueueGroup();
                    this._queueGroups.Add(priority, group);
                }
                group.Add(item);
            }
            return(item);
        }
Пример #10
0
        /// <summary>Removes a scheduler from the group.</summary>
        /// <param name="queue">The scheduler to be removed.</param>
        void RemoveQueueNeedsLock(QueuedTaskSchedulerQueue queue)
        {
            // Find the group that contains the queue and the queue's index within the group
            QueueGroup queueGroup = _queueGroups[queue._priority];
            int        index      = queueGroup.IndexOf(queue);

            // We're about to remove the queue, so adjust the index of the next
            // round-robin starting location if it'll be affected by the removal
            if (queueGroup.NextQueueIndex >= index)
            {
                queueGroup.NextQueueIndex--;
            }

            // Remove it
            queueGroup.RemoveAt(index);
        }
Пример #11
0
        public void Queue <T>(QueueGroupKey <T> queueGroupKey, T item)
        {
            lock (queueGroupKeyToExecutionTimeDict)
            {
                QueueGroup queueGroup = DictionaryExtension.ValueOrDefault(queueGroupKeyToExecutionTimeDict, queueGroupKey);
                if (queueGroup != null)
                {
                    // Runnable already pending with given QueueGroupKey
                    queueGroup.Queue.Add(item);
                    return;
                }
                queueGroup = new QueueGroup(queueGroupKey, new List <T>());
                queueGroupKeyToExecutionTimeDict.Add(queueGroupKey, queueGroup);

                queueGroup.Queue.Add(item);
                QueueIntern <T>(queueGroup);
            }
        }
Пример #12
0
        /// <summary>Creates and activates a new scheduling queue for this scheduler.</summary>
        /// <param name="priority">The priority level for the new queue.</param>
        /// <returns>The newly created and activated queue at the specified priority.</returns>
        public TaskScheduler ActivateNewQueue(int priority)
        {
            // Create the queue
            var createdQueue = new QueuedTaskSchedulerQueue(priority, this);

            // Add the queue to the appropriate queue group based on priority
            lock (_queueGroups)
            {
                if (!_queueGroups.TryGetValue(priority, out QueueGroup list))
                {
                    list = new QueueGroup();
                    _queueGroups.Add(priority, list);
                }
                list.Add(createdQueue);
            }

            // Hand the new queue back
            return(createdQueue);
        }
Пример #13
0
        private void CheckForPendingQueues()
        {
            lock (queueGroupKeyToExecutionTimeDict)
            {
                DateTime now = DateTime.Now;
                for (int a = pendingQueueGroups.Count; a-- > 0;)
                {
                    // Look at the last QueueGroup
                    QueueGroup queueGroup = pendingQueueGroups[a];
                    if (now < queueGroup.ExecutionTime)
                    {
                        // If the next QueueGroup is not ready, the others won't be, too
                        break;
                    }
                    pendingQueueGroups.RemoveAt(a);
                    AbstractQueueGroupKey queueGroupKey = queueGroup.QueueGroupKey;
                    queueGroupKeyToExecutionTimeDict.Remove(queueGroupKey);

                    lock (queueGroupKeyToExecuteDict)
                    {
                        IList <QueueGroup> currentExecutedQueueGroups = DictionaryExtension.ValueOrDefault(queueGroupKeyToExecuteDict, queueGroupKey);
                        if (currentExecutedQueueGroups != null)
                        {
                            // There is already a thread executing the key. Nothing to do here
                            currentExecutedQueueGroups.Add(queueGroup);
                            return;
                        }
                        // List container for concurrent QueueGroup of the same key
                        currentExecutedQueueGroups = new List <QueueGroup>();
                        queueGroupKeyToExecuteDict[queueGroupKey] = currentExecutedQueueGroups;
                    }
                    if (queueGroup.QueueGroupKey.InvokeFromGuiThread && SyncContext != null)
                    {
                        SyncContext.Post(ExecuteQueuedDelegate, queueGroup);
                        continue;
                    }
                    Queue(delegate()
                    {
                        ExecuteQueuedDelegate(queueGroup);
                    });
                }
            }
        }
Пример #14
0
        private void ExecuteQueuedDelegate(Object state)
        {
            QueueGroup            queueGroup    = (QueueGroup)state;
            AbstractQueueGroupKey queueGroupKey = queueGroup.QueueGroupKey;

            bool doRun = true;

            while (doRun)
            {
                try
                {
                    if (queueGroupKey is QueueGroupKey)
                    {
                        ((QueueGroupKey)queueGroupKey).QueuedDelegate.Invoke();
                    }
                    else
                    {
                        Delegate delegateObj = (Delegate)queueGroupKey.GetType().GetProperty("QueuedDelegate").GetValue(queueGroupKey, null);
                        delegateObj.DynamicInvoke(queueGroup.Queue);
                    }
                }
                finally
                {
                    lock (queueGroupKeyToExecuteDict)
                    {
                        IList <QueueGroup> currentExecutedQueueGroups = DictionaryExtension.ValueOrDefault(queueGroupKeyToExecuteDict, queueGroupKey);
                        if (currentExecutedQueueGroups.Count > 0)
                        {
                            // There is another queueGroup of the same key ready to be executed. Do it now immediately
                            queueGroup    = currentExecutedQueueGroups[0];
                            queueGroupKey = queueGroup.QueueGroupKey;
                            currentExecutedQueueGroups.RemoveAt(0);
                        }
                        else
                        {
                            queueGroupKeyToExecuteDict.Remove(queueGroupKey);
                            doRun = false;
                        }
                    }
                }
            }
        }
Пример #15
0
 public NextQueue GetQueue(IHttpContext context)
 {
     if (Type == ThreadQueueType.Single)
     {
         return(QueueGroup.Queues[0]);
     }
     else if (Type == ThreadQueueType.Multiple)
     {
         return(QueueGroup.Next());
     }
     else if (Type == ThreadQueueType.DataUnique)
     {
         string value = null;
         if (UniqueName != null)
         {
             if (string.Compare(UniqueName, "$path", true) == 0)
             {
                 value = context.Request.GetSourcePath();
             }
             else if (UniqueName.IndexOf("__") == 0)
             {
                 return(mUniqueQueueGroup.Has(UniqueName.GetHashCode()));
             }
             else
             {
                 value = context.Request.Header[UniqueName];
                 if (value == null)
                 {
                     context.Data.TryGetString(UniqueName, out value);
                 }
             }
         }
         if (value == null)
         {
             value = context.Request.GetSourceUrl();
         }
         return(mUniqueQueueGroup.Has(value.GetHashCode()));
     }
     return(QueueGroup.Next());
 }
Пример #16
0
    void Awake()
    {
        if (queuesSet)
        {
            Destroy(this);
            return;
        }

        for (int i = 0; i < queueGroups.Length; i++)
        {
            QueueGroup group = queueGroups[i];
            for (int m = 0; m < group.materials.Length; m++)
            {
                if (group.materials[m] != null)
                {
                    group.materials[m].renderQueue = group.queue;
                }
            }
        }

        Destroy(this);
    }
Пример #17
0
        protected void QueueIntern <T>(QueueGroup queueGroup)
        {
            bool queueGroupAdded = false;

            // Insert the QueueGroup at the right position of pending QueueGroups
            // At index 0 is the latest of all, at max-index the next triggering QueueGroup
            for (int a = 0, size = pendingQueueGroups.Count; a < size; a++)
            {
                QueueGroup pendingQueueGroup = pendingQueueGroups[a];
                if (queueGroup.ExecutionTime >= pendingQueueGroup.ExecutionTime)
                {
                    // If new QueueGroup executes AFTER or EQUAL TO the current investigated QueueGroup,
                    // insert the new QueueGroup BEFORE in the list
                    pendingQueueGroups.Insert(a, queueGroup);
                    queueGroupAdded = true;
                    break;
                }
            }
            if (!queueGroupAdded)
            {
                pendingQueueGroups.Add(queueGroup);
            }
        }
Пример #18
0
        /// <inheritdoc/>
        public IMatchmakerQueueTask <T> EnqueueGroup(EntityGroup <T> entities, EventHandler <MatchmakingStateChangedEventArgs <T> > callback = null)
        {
            RankingMatchmakerQueueTask <T> task = new RankingMatchmakerQueueTask <T>(this, entities, callback);
            QueueGroup queueGroup = new QueueGroup {
                task = task
            };

            MatchRankingContext <T> context = new MatchRankingContext <T>(DiscardThreshold);

            //Look at all other entities in queue and rate them
            lock (queueSnapshot)
                AddMatchesToQueueGroup(queueGroup, queueSnapshot, context);

            lock (inQueue)
            {
                //Rate those to be added in future
                AddMatchesToQueueGroup(queueGroup, inQueue, context);

                //Add to in queue for next tick/flush
                inQueue.Enqueue(queueGroup);
            }

            return(task);
        }
Пример #19
0
 /// <summary>Find the next task that should be executed, based on priorities and fairness and the like.</summary>
 /// <param name="targetTask">The found task, or null if none was found.</param>
 /// <param name="queueForTargetTask">
 /// The scheduler associated with the found task.  Due to security checks inside of TPL,
 /// this scheduler needs to be used to execute that task.
 /// </param>
 private void FindNextTask_NeedsLock(out Task targetTask, out QueuedTaskSchedulerQueue queueForTargetTask)
 {
     targetTask         = null;
     queueForTargetTask = null;
     foreach (KeyValuePair <int, QueueGroup> pair in this._queueGroups)
     {
         QueueGroup group = pair.Value;
         foreach (int num in group.CreateSearchOrder())
         {
             queueForTargetTask = group[num];
             Queue <Task> queue = queueForTargetTask._workItems;
             if (queue.Count > 0)
             {
                 targetTask = queue.Dequeue();
                 if (queueForTargetTask._disposed && (queue.Count == 0))
                 {
                     this.RemoveQueue_NeedsLock(queueForTargetTask);
                 }
                 group.NextQueueIndex = (group.NextQueueIndex + 1) % pair.Value.Count;
                 break;
             }
         }
     }
 }
Пример #20
0
        public static string DecideColumnColour(QueueGroup queueGroup, MonitorData monitorData)
        {
            double seerviceLevel = (Convert.ToDouble(monitorData.HandledWithinSL) / Convert.ToDouble(monitorData.Offered)) * 100;

            return(seerviceLevel >= queueGroup.SLA_Percent ? Constants.Green : Constants.Red);
        }
Пример #21
0
        public async Task QueueUp(DiscordChannel channel, DiscordMember user, PlayerRole role, DiscordMember other = null)
        {
            var inhouseQueue = InhouseQueues.FirstOrDefault(x => x.ChannelId == channel.Id);

            if (inhouseQueue == null)
            {
                return;
            }

            var           queueGroup    = inhouseQueue.PlayersInQueue.FirstOrDefault(x => x.Players.Any(y => y.Player.Id == user.Id));
            InhousePlayer inhousePlayer = null;

            if (queueGroup == null)
            {
                queueGroup    = new QueueGroup();
                inhousePlayer = new InhousePlayer(user);
                queueGroup.Players.Add(inhousePlayer);
                inhouseQueue.PlayersInQueue.Add(queueGroup);
            }
            else
            {
                inhousePlayer = queueGroup.Players.FirstOrDefault(x => x.Player.Id == user.Id);
            }

            // if the player in question is already a fill player, do nothing
            if (!inhousePlayer.QueuedRoles[PlayerRole.Fill])
            {
                switch (role)
                {
                case PlayerRole.Top:
                    inhousePlayer.QueuedRoles[PlayerRole.Top] = true;
                    break;

                case PlayerRole.Jgl:
                    inhousePlayer.QueuedRoles[PlayerRole.Jgl] = true;
                    break;

                case PlayerRole.Mid:
                    inhousePlayer.QueuedRoles[PlayerRole.Mid] = true;
                    break;

                case PlayerRole.Bot:
                    inhousePlayer.QueuedRoles[PlayerRole.Bot] = true;
                    break;

                case PlayerRole.Sup:
                    inhousePlayer.QueuedRoles[PlayerRole.Sup] = true;
                    break;

                case PlayerRole.Fill:
                    inhousePlayer.QueuedRoles[PlayerRole.Top]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Jgl]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Mid]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Bot]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Sup]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Fill] = true;
                    break;
                }

                if (inhousePlayer.QueuedRoles[PlayerRole.Top] && inhousePlayer.QueuedRoles[PlayerRole.Jgl] &&
                    inhousePlayer.QueuedRoles[PlayerRole.Mid] && inhousePlayer.QueuedRoles[PlayerRole.Bot] && inhousePlayer.QueuedRoles[PlayerRole.Sup])
                {
                    inhousePlayer.QueuedRoles[PlayerRole.Top]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Jgl]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Mid]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Bot]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Sup]  = false;
                    inhousePlayer.QueuedRoles[PlayerRole.Fill] = true;
                }
            }

            // attempt to join team if provided
            if (other != null)
            {
                await TeamUp(channel, user, other).ConfigureAwait(false);
            }
            else
            {
                await ShowQueue(channel).ConfigureAwait(false);
            }

            await AttemptMatchmake(channel).ConfigureAwait(false);
        }