예제 #1
0
        /// <summary>
        /// Removes a pending request for an Agent match from the queue
        /// </summary>
        private bool RemoveFromQueue(PendingAgentMatchRequestQueueItem queueItem)
        {
            if (null != queueItem)
            {
                lock (_syncRoot)
                {
                    if (_matchMakerState != MatchMakerState.Terminating &&
                        _matchMakerState != MatchMakerState.Terminated)
                    {
                        // if not terminating, process the queue removal else this will be
                        // done by the shutdown operation.
                        return(_pendingAgentRequestQueueItems.Remove(queueItem));
                    }
                }
            }

            return(false);
        }
예제 #2
0
            internal void Process()
            {
                Agent agent = null;

                // Try to find a match synchronously
                agent = MatchAndAllocate();

                if (agent != null)
                {
                    // Completes the operation synchronously
                    this.SetAsCompleted(agent, false);
                }
                else
                {
                    //Add the agent match request to the list of pending requests and start a timer
                    lock (_matchMaker._syncRoot)
                    {
                        if (_matchMaker._matchMakerState < MatchMakerState.Terminating)
                        {
                            // Using the match maker timer wheel to trigger the operation time out.
                            TimerItem timerItem = new TimerItem(_matchMaker._timerWheel, new TimeSpan(0, 0, 0, _matchMaker._configuration.MaxWaitTimeOut, 0));
                            timerItem.Expired += new EventHandler(HandlePendingRequestTimeOut);
                            timerItem.Start();

                            //create a queue item and cache a reference
                            _queueItem = new PendingAgentMatchRequestQueueItem(_requestor, this, timerItem);

                            //add the queueItem to the queue
                            _matchMaker._pendingAgentRequestQueueItems.Add(_queueItem);
                            return;
                        }
                    }

                    this.SetAsCompleted(new OperationFailureException("AcdAgentMatchMaker is terminating and cannot process any new async requests"), false);
                }
            }
예제 #3
0
        /// <summary>
        /// Determines whether an agent who becomes available has the correct skillset to be connected
        /// to a customer who is waiting. If it does, the agent is allocated.
        /// </summary>
        internal void HandleNewAvailableAgent(Agent agent)
        {
            PendingAgentMatchRequestQueueItem pendingRequestToBeRemoved = null;

            lock (_syncRoot)
            {
                foreach (PendingAgentMatchRequestQueueItem pendingRequestQueueItem in _pendingAgentRequestQueueItems)
                {
                    // Retrieve the associated asyncResult from the item in the queue
                    FindAgentAsyncResult asyncResult = pendingRequestQueueItem.FindAgentAsyncResult;

                    if (null == asyncResult)
                    {
                        continue;
                    }

                    //Check if the agent is a match for the current pending request
                    if (asyncResult.IsAgentMatch(agent))
                    {
                        //It is a match, allocate the Agent
                        _logger.Log("Allocating Agent " + agent.SignInAddress);

                        try
                        {
                            //It is a match, allocate the Agent
                            agent.Allocate(pendingRequestQueueItem._Requestor);
                            _logger.Log("Agent " + agent.SignInAddress + " is allocated to :" + agent.Owner.ToString());
                        }
                        catch (InvalidOperationException ex)
                        {
                            //this is a race condition where an agent got allocated while the pending
                            // request was still in the queue
                            _logger.Log("AcdAgentMatchMaker failed allocation of Agent " + agent.SignInAddress, ex);

                            return;
                        }

                        // if we allocate the agent, we need to remove the pending request from the queue
                        pendingRequestToBeRemoved = pendingRequestQueueItem;

                        //Stop the timer
                        TimerItem tmrItem = pendingRequestQueueItem._TmrItem;
                        if (null != tmrItem)
                        {
                            tmrItem.Stop();
                        }
                        break;
                    }
                }

                //Attempt to remove the pending operation from the queue
                //If it fails removing the pending request, the match maker is probably in terminating state
                //in which case, shut down will take care of the clean up.
                if (null != pendingRequestToBeRemoved)
                {
                    //let's remove the pend operation first to ensure that the async result does not
                    //get executed twice in a row.
                    this.RemoveFromQueue(pendingRequestToBeRemoved);
                    //Complete the async operation with success
                    pendingRequestToBeRemoved.FindAgentAsyncResult.SetAsCompleted(agent, false);
                }
            }
        }