ContactCenters
V. 0.9.9.

umontreal.iro.lecuyer.contactcenters.router
Class Router

java.lang.Object
  extended by umontreal.iro.lecuyer.contactcenters.router.Router
All Implemented Interfaces:
NewContactListener
Direct Known Subclasses:
AgentsPrefRouter, ExpDelayRouter, OverflowAndPriorityRouter, QueueAtLastGroupRouter, QueuePriorityRouter, QueueRatioOverflowRouter

public abstract class Router
extends Object
implements NewContactListener

Represents a contact router which can perform agent and contact selections. A router links the contact sources, agent groups and waiting queues together and acts as a central element of the contact center. It supports a certain number of contact types and contains slots for waiting queues and agent groups.

Dequeued contacts and freed agents are notified to the router through nested classes implementing the appropriate listener interfaces. These classes listen to the connected agent groups and waiting queues only. Agent groups and waiting queues are connected to the router using the setAgentGroup(int,AgentGroup) and setWaitingQueue(int,WaitingQueue) methods, respectively. During connection, they are assigned a numerical identifier to be referred to efficiently during routing.

This abstract class does not implement any routing policy. To implement such a policy, many informations must be provided in a subclass: data structures, algorithms for agent, waiting queue and contact selections, and an algorithm to automatically clear waiting queues. A router can also specify what happens when a contact is served or abandons. We now examine these elements in more details. Data structures are encoded into fields, and usually consist of a type-to-group and a group-to-type maps, or matrices of ranks. Algorithms are provided by overriding methods.

When a new contact is notified through its newContact(Contact) method specified by the NewContactListener interface, the router performs agent selection, i.e., it tries to assign an agent to the contact. The selectAgent(Contact) method is used to select the agent, and selectWaitingQueue(Contact) is called if no free agent is available.

The router supports contact rerouting which works as follows. When a contact is queued, the router gets a delay using getReroutingDelay(DequeueEvent,int). If that delay is finite and greater than or equal to 0, a rerouting event is scheduled. When such an event happens, the router tries to use selectAgent(DequeueEvent,int) to assign an agent to a queued contact. If this rerouting fails, the router uses selectWaitingQueue(DequeueEvent,int) to decide if the contact should be dropped, transferred into another queue, or kept in the same queue. After this queue reselection has happened, the router uses getReroutingDelay(DequeueEvent,int) again to decide if a subsequent rerouting will happen. By default, this functionality is disabled. One has to override getReroutingDelay(DequeueEvent,int) and selectAgent(DequeueEvent,int) to use rerouting.

When an agent becomes free, the router must perform contact selection, i.e., it must try to assign a queued contact to the free agent through the checkFreeAgents(AgentGroup,Agent) method. The checkFreeAgents(AgentGroup,Agent) method is called, and usually calls selectContact(AgentGroup,Agent) to get queued contacts. If no queued contact is available for the free agent, the agent remains free.

The router also supports agent rerouting which works as follows. If an agent has finished the service of a contact and cannot find a new contact to serve, before letting the agent idle, the router gets a delay using getReroutingDelay(Agent,int). If this delay is finite and greater than or equal to 0, the router schedules an event that will try to assign a new contact to the agent. The contact is selected using the selectContact(Agent,int) method. As with contact rerouting, agent rerouting can happen multiple times and it is disabled by default. One needs to use detailed agent groups considering individual agents and override getReroutingDelay(Agent,int) as well as selectContact(Agent,int) to take advantage of agent rerouting.

At some moments during the day, queued contacts may never be served, because no skilled agent is present. For example, when the center closes, all agents leave and queued contacts are forced to wait forever or abandon. To avoid this, an additional algorithm may be implemented in checkWaitingQueues(AgentGroup) to automatically clear the queues when no agent can serve contacts. This clearing is disabled by default but can be enabled by using setClearWaitingQueue(int,boolean) or setClearWaitingQueues(boolean).

Finally, the moment a contact exits can be controlled. By default, dequeued and served contacts exit the system, but it is possible to override methods in this class to change this behavior, e.g., transfer a dequeued contact to another queue, transfer a served contact to another agent, etc.

Note that the blocking, dequeue, end-contact and end-service indicators Integer.MAX_VALUE - 1000 through Integer.MAX_VALUE are reserved for present and future use by routers. Dequeue type 0 is also reserved, and represents the beginning of the service for a queued contact. The constant DEQUEUETYPE_BEGINSERVICE can be used to represent this.

Note: the ExitedContactListener implementations are notified in the order of the list returned by getExitedContactListeners(), and an exited-contact listener modifying the list of listeners by using addExitedContactListener(ExitedContactListener) or removeExitedContactListener(ExitedContactListener) could result in unpredictable behavior.


Field Summary
static int BLOCKTYPE_CANTQUEUE
          Contact blocking type occurring when a contact cannot be queued, i.e., selectWaitingQueue(Contact) returns null.
static int BLOCKTYPE_NOLINE
          Contact blocking type occurring when there is no communication channel available in the trunk group associated with an incoming contact.
static int BLOCKTYPE_QUEUEFULL
          Contact blocking type occurring when the total queue capacity is exceeded upon the arrival of a contact.
static int DEQUEUETYPE_BEGINSERVICE
          Contact dequeueing type representing the beginning of the service.
static int DEQUEUETYPE_FANTOM
          Contact dequeue type used to remove multiple copies of a contact from waiting queues.
static int DEQUEUETYPE_NOAGENT
          Contact dequeuing type occurring when a waiting queue is cleared because there is no agent in the system capable of serving the contact.
static int DEQUEUETYPE_TRANSFER
          Contact dequeue type used when transferring a contact from a waiting to another waiting queue.
protected  int dqTypeRet
          Contains the dequeue type used when a contact leaves a queue to enter a new one.
 
Constructor Summary
Router(int numTypes, int numQueues, int numGroups)
          Constructs a new router with numTypes contact types, numQueues waiting queues, and numGroups agent groups.
 
Method Summary
 void addExitedContactListener(ExitedContactListener listener)
          Adds the exited-contact listener listener to this router.
 Iterator<AgentReroutingEvent> agentReroutingEventsIterator()
          Constructs and returns an iterator for the agent rerouting events.
protected  void beginService(EndServiceEvent ev)
          This method is called when the service of a contact, represented by the event ev, begins.
abstract  boolean canServe(int i, int k)
          Returns true if and only if some agents in group i are authorized to serve contacts of type k by this router.
protected  boolean checkFreeAgents(AgentGroup group, Agent agent)
          This method is called when the agent agent in agent group group becomes free.
protected abstract  void checkWaitingQueues(AgentGroup group)
          This method is called when the agent group group contains no more online agents, i.e., AgentGroup.getNumAgents() returns 0.
 void clearExitedContactListeners()
          Removes all the exited-contact listeners registered to this router.
 Iterator<ContactReroutingEvent> contactReroutingEventsIterator()
          Constructs and returns an iterator for the contact rerouting events.
protected  void dequeued(DequeueEvent ev)
          This method is called when a contact leaves a waiting queue, ev representing the corresponding dequeue event.
protected  void endContact(EndServiceEvent ev)
          This method is called when the communication between a contact and an agent is finished.
protected  void endService(EndServiceEvent ev)
          This method is called when the service (communication and after-contact work) of a contact in an agent group has ended.
protected  void enqueued(DequeueEvent ev)
          This method is called when a contact is enqueued, ev representing the dequeue event.
 void exitBlocked(Contact contact, int bType)
          This method can be called when the contact contact was blocked by the router with blocking type bType.
 void exitDequeued(DequeueEvent ev)
          This method must be called to notify that a contact exited the system after being dequeued, ev representing the dequeue event.
 void exitServed(EndServiceEvent ev)
          This method must be called to notify a contact exiting the system after an end of service with end-service event ev.
 String formatAgentGroups()
          Formats the connected agent groups as a string.
 String formatWaitingQueues()
          Formats the connected waiting queues as a string.
 AgentGroup getAgentGroup(int i)
          Returns the agent group with index i for this router.
 AgentGroupListener getAgentGroupListener()
          Returns the agent-group listener registered with each agent group connected to this router.
 AgentGroup[] getAgentGroups()
          Returns an array containing the agent groups attached to this router.
 Map<Agent,AgentReroutingEvent> getAgentReroutingEvents()
          Returns an unmodifiable map containing the currently scheduled agent rerouting events.
 SingleTypeContactFactory getContactFactory(int k)
          Returns the contact factory used by the simulator to create contacts of type k.
 Map<DequeueEvent,ContactReroutingEvent> getContactReroutingEvents()
          Returns an unmodifiable map containing the currently scheduled contact rerouting events.
 int getCurrentQueueSize()
          Returns the total number of contacts in the connected waiting queues.
 String getDescription()
           
 List<Dialer> getDialers(int i)
          Returns a list containing the dialers which will be triggered when the service of a contact by an agent in group i ends.
 List<ExitedContactListener> getExitedContactListeners()
          Returns an unmodifiable list containing all the exited-contact listeners registered with this router.
 Comparator<? super DequeueEvent> getNeededWaitingQueueComparator(int q)
          Determines how contacts in queue should be compared with each other for waiting queue q.
 WaitingQueueStructure getNeededWaitingQueueStructure(int q)
          Returns the needed data structure for waiting queue with index q.
 int getNumAgentGroups()
          Returns the number of agent groups supported by this router.
 int getNumContactTypes()
          Returns the number of contact types supported by this router.
 int getNumWaitingQueues()
          Returns the number of waiting queues supported by this router.
protected  double getReroutingDelay(Agent agent, int numReroutingsDone)
          Returns the delay, in simulation time units, after which an agent agent should try a new time to get a contact to serve.
protected  double getReroutingDelay(DequeueEvent dqEv, int numReroutingsDone)
          Returns the delay, in simulation time units, after which a queued contact should be rerouted.
 int getTotalQueueCapacity()
          Returns the total capacity of the waiting queues for this router.
 WaitingQueue getWaitingQueue(int q)
          Returns the waiting queue with index q for this router.
 WaitingQueueListener getWaitingQueueListener()
          Returns the waiting-queue listener registered with each waiting queue connected to this router.
 WaitingQueue[] getWaitingQueues()
          Returns an array containing the waiting queues attached to this router.
 WaitingQueueType getWaitingQueueType()
          Returns an indicator describing how the implemented routing policies organizes waiting queues.
 void init()
          This method is called at the beginning of the simulation to reset the state of this router.
 boolean isKeepingReroutingEvents()
          Determines if this router keeps track of all rerouting events scheduled.
 boolean mustClearWaitingQueue(int q)
          Determines if the router must clear the waiting queue q when all queued contacts cannot be served since no agent capable of serving them is online anymore.
 boolean needsDetailedAgentGroup(int i)
          Determines if the agent group i should consider individual agents.
 void newContact(Contact contact)
          This method is called when the new contact contact enters in the system and should not be overridden.
 void notifyBlocked(Contact contact, int bType)
          Notifies every registered listener that the contact contact was blocked with blocking type bType.
 void notifyDequeued(DequeueEvent ev)
          Notifies every registered listener that a contact left the waiting queue, this event being represented by ev.
 void notifyServed(EndServiceEvent ev)
          Notifies every registered listener that a contact was served, the service being represented by the end-service event ev.
 void removeExitedContactListener(ExitedContactListener listener)
          Removes the exited-contact listener listener from this router.
 void restore(RouterState state)
          Restores the state state of this router.
 RouterState save()
          Saves the state of this router, and returns the resulting state object.
protected abstract  EndServiceEvent selectAgent(Contact contact)
          Begins the service of the contact contact by trying to assign it a free agent.
protected  EndServiceEvent selectAgent(DequeueEvent dqEv, int numReroutingsDone)
          Selects an agent for serving a queued contact in the context of rerouting.
protected  DequeueEvent selectContact(AgentGroup group, Agent agent)
          Returns a dequeue event representing a queued contact to be served by the agent agent in agent group group.
protected  DequeueEvent selectContact(Agent agent, int numReroutingsDone)
          Selects a new contact for the agent agent, in the context of rerouting.
protected abstract  DequeueEvent selectWaitingQueue(Contact contact)
          Selects a waiting queue and puts the contact contact into it.
protected  DequeueEvent selectWaitingQueue(DequeueEvent dqEv, int numReroutingsDone)
          Selects a waiting queue for a queued contact in the context of rerouting.
 void setAgentGroup(int i, AgentGroup group)
          Associates the agent group group with the index i in the router.
 void setClearWaitingQueue(int q, boolean b)
          Sets the clear-waiting-queue indicator for the waiting queue q to b.
 void setClearWaitingQueues(boolean b)
          Sets the clear-waiting-queue indicator to b for all waiting queues.
 void setContactFactory(int k, SingleTypeContactFactory factory)
          Sets the contact factory used to create contacts of type k to factory.
 void setKeepingReroutingEvents(boolean keep)
          Sets the keep-rerouting-events indicator to keep.
 void setTotalQueueCapacity(int capacity)
          Sets the total queue capacity to capacity for this router.
 void setWaitingQueue(int q, WaitingQueue queue)
          Associates the waiting queue queue with the index q in the router.
protected  void startDialers(AgentGroup group)
          Starts the dialers after the service of a contact by an agent in group group.
 String toLongString()
          Returns a string representation of detailed information about the router.
 String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

BLOCKTYPE_NOLINE

public static final int BLOCKTYPE_NOLINE
Contact blocking type occurring when there is no communication channel available in the trunk group associated with an incoming contact.

See Also:
Constant Field Values

BLOCKTYPE_QUEUEFULL

public static final int BLOCKTYPE_QUEUEFULL
Contact blocking type occurring when the total queue capacity is exceeded upon the arrival of a contact.

See Also:
Constant Field Values

BLOCKTYPE_CANTQUEUE

public static final int BLOCKTYPE_CANTQUEUE
Contact blocking type occurring when a contact cannot be queued, i.e., selectWaitingQueue(Contact) returns null.

See Also:
Constant Field Values

DEQUEUETYPE_BEGINSERVICE

public static final int DEQUEUETYPE_BEGINSERVICE
Contact dequeueing type representing the beginning of the service.

See Also:
Constant Field Values

DEQUEUETYPE_NOAGENT

public static final int DEQUEUETYPE_NOAGENT
Contact dequeuing type occurring when a waiting queue is cleared because there is no agent in the system capable of serving the contact.

See Also:
Constant Field Values

DEQUEUETYPE_FANTOM

public static int DEQUEUETYPE_FANTOM
Contact dequeue type used to remove multiple copies of a contact from waiting queues. When a contact has to wait in more than one waiting queues, it can exit any of these queues at any time. When the contact is dequeued, e.g., because it is transferred to an agent. In this case, the contact also needs to be removed from other queues. This dequeue type can be used to avoid such contacts being counted several times by statistical facilities.


DEQUEUETYPE_TRANSFER

public static int DEQUEUETYPE_TRANSFER
Contact dequeue type used when transferring a contact from a waiting to another waiting queue.


dqTypeRet

protected int dqTypeRet
Contains the dequeue type used when a contact leaves a queue to enter a new one. By default, this is set to 1.

Constructor Detail

Router

public Router(int numTypes,
              int numQueues,
              int numGroups)
Constructs a new router with numTypes contact types, numQueues waiting queues, and numGroups agent groups.

Parameters:
numTypes - number of contact types.
numQueues - number of waiting queues.
numGroups - number of agent groups.
Throws:
IllegalArgumentException - if any argument is negative.
Method Detail

isKeepingReroutingEvents

public boolean isKeepingReroutingEvents()
Determines if this router keeps track of all rerouting events scheduled. By default, these events are discarded, i.e., they are stored in the event list only.

Returns:
true if the router keeps track of the rerouting events, false otherwise.

setKeepingReroutingEvents

public void setKeepingReroutingEvents(boolean keep)
Sets the keep-rerouting-events indicator to keep.

Parameters:
keep - the value of the indicator.

contactReroutingEventsIterator

public Iterator<ContactReroutingEvent> contactReroutingEventsIterator()
Constructs and returns an iterator for the contact rerouting events. If isKeepingReroutingEvents() returns true, the iterator is constructed from the set returned by getContactReroutingEvents(). Otherwise, an iterator traversing the event list and filtering the appropriate events is constructed and returned.

Returns:
the iterator for contact rerouting events.

getContactReroutingEvents

public Map<DequeueEvent,ContactReroutingEvent> getContactReroutingEvents()
Returns an unmodifiable map containing the currently scheduled contact rerouting events. Each key of this map corresponds to a dequeue event while each value corresponds to an instance of ContactReroutingEvent. If rerouting events are not kept, this throws an IllegalStateException.

Returns:
the map of contact rerouting events.
Throws:
IllegalStateException - if rerouting events are not kept.

agentReroutingEventsIterator

public Iterator<AgentReroutingEvent> agentReroutingEventsIterator()
Constructs and returns an iterator for the agent rerouting events. If isKeepingReroutingEvents() returns true, the iterator is constructed from the set returned by getAgentReroutingEvents(). Otherwise, an iterator traversing the event list and filtering the appropriate events is constructed and returned.

Returns:
the iterator for agent rerouting events.

getAgentReroutingEvents

public Map<Agent,AgentReroutingEvent> getAgentReroutingEvents()
Returns an unmodifiable map containing the currently scheduled agent rerouting events. Each key of this map corresponds to an Agent object while each value corresponds to an instance of AgentReroutingEvent. If rerouting events are not kept, this throws an IllegalStateException.

Returns:
the map of agent rerouting events.
Throws:
IllegalStateException - if rerouting events are not kept.

save

public RouterState save()
Saves the state of this router, and returns the resulting state object.

Returns:
the current state of this router.

restore

public void restore(RouterState state)
Restores the state state of this router.

Parameters:
state - the saved state of the router.

getTotalQueueCapacity

public int getTotalQueueCapacity()
Returns the total capacity of the waiting queues for this router. This capacity determines the maximal number of contacts that can be queued simultaneously by this router. By default, this is Integer.MAX_VALUE, i.e., infinite.

Returns:
the total queue capacity of the router.

setTotalQueueCapacity

public void setTotalQueueCapacity(int capacity)
Sets the total queue capacity to capacity for this router. If the given capacity is negative, an IllegalArgumentException is thrown. If the capacity is less than the total number of queued contacts, this throws an IllegalStateException.

Parameters:
capacity - the new total queue capacity.
Throws:
IllegalArgumentException - if the given capacity is negative.
IllegalStateException - if the given capacity is less than the actual number of queued contacts.

getCurrentQueueSize

public int getCurrentQueueSize()
Returns the total number of contacts in the connected waiting queues.

Returns:
the total number of contacts in queues.

getNumContactTypes

public int getNumContactTypes()
Returns the number of contact types supported by this router.

Returns:
the supported number of contact types.

getNumAgentGroups

public int getNumAgentGroups()
Returns the number of agent groups supported by this router.

Returns:
the number of agent groups.

getNumWaitingQueues

public int getNumWaitingQueues()
Returns the number of waiting queues supported by this router.

Returns:
the number of waiting queues.

getWaitingQueue

public WaitingQueue getWaitingQueue(int q)
Returns the waiting queue with index q for this router. If q is less than 0 or greater than or equal to the number of supported queues, an exception is thrown. Calling the WaitingQueue.getId() method on the returned waiting queue should return q, unless this method returns null.

Parameters:
q - the index of the queue.
Returns:
the associated waiting queue, or null if no queue is defined for this index.
Throws:
IndexOutOfBoundsException - if q is negative or greater than or equal to getNumWaitingQueues().

getWaitingQueues

public WaitingQueue[] getWaitingQueues()
Returns an array containing the waiting queues attached to this router.

Returns:
the waiting queues attached to this router.

setWaitingQueue

public void setWaitingQueue(int q,
                            WaitingQueue queue)
Associates the waiting queue queue with the index q in the router. The method tries to set the queue id to q and registers a waiting-queue listener for queue to be notified about automatic dequeues if needed. If a waiting queue was previously associated with the index, the router's waiting-queue listener is removed from that previous waiting queue.

Note that some routers assume that waiting queues use FIFO discipline. In this case, one should use StandardWaitingQueue instances only. Using PriorityWaitingQueue may lead to routing not corresponding to the defined policy.

Parameters:
q - the index of the queue.
queue - the queue to be associated.
Throws:
IllegalStateException - if the queue id was already set to another value than q.
IndexOutOfBoundsException - if q is negative or greater than or equal to getNumWaitingQueues().

mustClearWaitingQueue

public boolean mustClearWaitingQueue(int q)
Determines if the router must clear the waiting queue q when all queued contacts cannot be served since no agent capable of serving them is online anymore. By default, this is set to false.

Parameters:
q - the index of the checked waiting queue.
Returns:
the clear-waiting-queue indicator.
Throws:
IndexOutOfBoundsException - if q is negative or greater than or equal to getNumWaitingQueues().

setClearWaitingQueue

public void setClearWaitingQueue(int q,
                                 boolean b)
Sets the clear-waiting-queue indicator for the waiting queue q to b. See mustClearWaitingQueue(int) for more information.

Parameters:
q - the index of the affected waiting queue.
b - the new value of the indicator.
Throws:
IndexOutOfBoundsException - if q is negative or greater than or equal to getNumWaitingQueues().
See Also:
mustClearWaitingQueue(int)

setClearWaitingQueues

public void setClearWaitingQueues(boolean b)
Sets the clear-waiting-queue indicator to b for all waiting queues. See mustClearWaitingQueue(int) for more information.

Parameters:
b - the new value of the indicator.
See Also:
mustClearWaitingQueue(int)

getContactFactory

public SingleTypeContactFactory getContactFactory(int k)
Returns the contact factory used by the simulator to create contacts of type k. This factory may be used by some routing policies to obtain information such as the distribution of service times. When a routing policy uses this information, the simulator should create contacts of type k with this single-type contact factory only.

Parameters:
k - the contact type identifier.
Returns:
the contact factory.

setContactFactory

public void setContactFactory(int k,
                              SingleTypeContactFactory factory)
Sets the contact factory used to create contacts of type k to factory.

Parameters:
k - the contact type identifier.
factory - the contact factory.

getAgentGroup

public AgentGroup getAgentGroup(int i)
Returns the agent group with index i for this router. If i is less than 0 or greater than or equal to the number of groups, an exception is thrown. Calling AgentGroup.getId() on the returned group should return i, unless this method returns null.

Parameters:
i - the index of the agent group.
Returns:
the associated agent group, or null if no agent group is defined for this index.
Throws:
IndexOutOfBoundsException - if i is negative or greater than or equal to getNumAgentGroups().

getAgentGroups

public AgentGroup[] getAgentGroups()
Returns an array containing the agent groups attached to this router.

Returns:
the attached agent groups.

setAgentGroup

public void setAgentGroup(int i,
                          AgentGroup group)
Associates the agent group group with the index i in the router. The method tries to set the identifier of the group to i and registers an agent-group listener to be notified about agents becoming free in order to perform contact selection. If an agent group was previously associated with the index, the router's agent-group listener is removed from that previous agent group.

Parameters:
i - the index of the agent group.
group - the agent group to be associated.
Throws:
IllegalStateException - if the group id was already set to another value than i.
IndexOutOfBoundsException - if i is negative or greater than or equal to getNumAgentGroups().

getDialers

public List<Dialer> getDialers(int i)
Returns a list containing the dialers which will be triggered when the service of a contact by an agent in group i ends. This list, which may contain only non-null instances of the Dialer class, should be used instead of an agent-group listener to activate the dialer. As opposed to an agent-group listener requesting dialers to try calls, dialers in the returned list are activated only after contact selection for agents in group i is done, and they are guaranteed to be activated in the order given by the list.

Parameters:
i - the index of the agent group.
Returns:
the list of dialers.
Throws:
ArrayIndexOutOfBoundsException - if the agent group index is out of bounds.

canServe

public abstract boolean canServe(int i,
                                 int k)
Returns true if and only if some agents in group i are authorized to serve contacts of type k by this router.

Parameters:
i - the agent group index.
k - the contact type index.
Returns:
determines if contacts can be served.

needsDetailedAgentGroup

public boolean needsDetailedAgentGroup(int i)
Determines if the agent group i should consider individual agents. This does not determine directly how the agent group returned by getAgentGroup(int) is implemented. This method only gives clues to a simulator on how to construct the concerned agent group.

Parameters:
i - the index of the agent group.
Returns:
the detailed status of the agent group.

getWaitingQueueType

public WaitingQueueType getWaitingQueueType()
Returns an indicator describing how the implemented routing policies organizes waiting queues. The supported modes of organization cover the most common cases only: waiting queues corresponding to contact types or agent groups. For any other modes, the WaitingQueueType.GENERAL must be used.

By default, this method returns WaitingQueueType.GENERAL.

Returns:
the organization mode of waiting queues.

getNeededWaitingQueueStructure

public WaitingQueueStructure getNeededWaitingQueueStructure(int q)
Returns the needed data structure for waiting queue with index q. This method is used by the simulator to get clues on how to construct the waiting queue; it does not affect directly the implementation of the waiting queue returned by getWaitingQueue(int). By default, this returns WaitingQueueStructure.LIST.

Parameters:
q - the index of the waiting queue.
Returns:
the structure indicator.

getNeededWaitingQueueComparator

public Comparator<? super DequeueEvent> getNeededWaitingQueueComparator(int q)
Determines how contacts in queue should be compared with each other for waiting queue q. This comparator is used by a simulator to construct a waiting queue if getNeededWaitingQueueStructure(int) returns WaitingQueueStructure.SORTEDSET or WaitingQueueStructure.PRIORITY. By default, this returns null.

Parameters:
q - the index of the waiting queue.
Returns:
the waiting queue comparator.

newContact

public void newContact(Contact contact)
This method is called when the new contact contact enters in the system and should not be overridden. The Contact.setRouter(Router) method is first used to set the router of the new contact to this object. Then, if Contact.getTrunkGroup() returns a non-null value, a communication channel is allocated. If no communication channel is available for the contact, the contact is blocked with blocking type BLOCKTYPE_NOLINE. If the contact has no associated trunk group or if a communication channel could be successfully allocated, the selectAgent(Contact) method is called to try to assign it an agent. In case of failure, i.e., selectAgent(Contact) returns null, the router tries to queue the contact. If the total queue size is equal to the total queue capacity, or if selectWaitingQueue(Contact) returns null, the contact is blocked with blocking type BLOCKTYPE_QUEUEFULL or BLOCKTYPE_CANTQUEUE, respectively.

Specified by:
newContact in interface NewContactListener
Parameters:
contact - the arrived contact.
Throws:
IllegalStateException - if Contact.getRouter() returns a non-null value before the router is set.
IllegalArgumentException - if the contact type identifier of the contact is negative or greater than or equal to getNumContactTypes().

addExitedContactListener

public void addExitedContactListener(ExitedContactListener listener)
Adds the exited-contact listener listener to this router. If the listener is already registered, nothing happens.

Parameters:
listener - the listener being added.
Throws:
NullPointerException - if listener is null.

removeExitedContactListener

public void removeExitedContactListener(ExitedContactListener listener)
Removes the exited-contact listener listener from this router.

Parameters:
listener - the exited contact listener being removed.

clearExitedContactListeners

public void clearExitedContactListeners()
Removes all the exited-contact listeners registered to this router.


getExitedContactListeners

public List<ExitedContactListener> getExitedContactListeners()
Returns an unmodifiable list containing all the exited-contact listeners registered with this router.

Returns:
the list of all registered exited-contact listeners.

notifyBlocked

public void notifyBlocked(Contact contact,
                          int bType)
Notifies every registered listener that the contact contact was blocked with blocking type bType.

Parameters:
contact - the blocked contact.
bType - the blocking type.

notifyDequeued

public void notifyDequeued(DequeueEvent ev)
Notifies every registered listener that a contact left the waiting queue, this event being represented by ev.

Parameters:
ev - the event representing the contact having left the queue.

notifyServed

public void notifyServed(EndServiceEvent ev)
Notifies every registered listener that a contact was served, the service being represented by the end-service event ev.

Parameters:
ev - the end-service event representing the end of the service.

exitServed

public void exitServed(EndServiceEvent ev)
This method must be called to notify a contact exiting the system after an end of service with end-service event ev. It notifies any registered exited-contact listener, and releases the communication channel taken by the contact. This must be called after the communication between the contact and an agent, before after-contact work.

Parameters:
ev - the end-service event.

exitDequeued

public void exitDequeued(DequeueEvent ev)
This method must be called to notify that a contact exited the system after being dequeued, ev representing the dequeue event. It notifies any registered exited-contact listener, and releases the communication channel taken by the contact.

Parameters:
ev - the dequeue event.

exitBlocked

public void exitBlocked(Contact contact,
                        int bType)
This method can be called when the contact contact was blocked by the router with blocking type bType. It notifies any registered exited-contact listener, and releases the communication channel taken by the contact. The bType = BLOCKTYPE_NOLINE value is reserved for the special case where there is no available communication channel for the contact.

Parameters:
contact - the contact being blocked.
bType - the blocking type.

startDialers

protected void startDialers(AgentGroup group)
Starts the dialers after the service of a contact by an agent in group group. This method is called after checkFreeAgents(AgentGroup,Agent) and should call the Dialer.dial() method on one or more dialers. The default implementation starts all the dialers in the list getDialers (group.getId()).

Parameters:
group - the agent group being notified.

init

public void init()
This method is called at the beginning of the simulation to reset the state of this router.


selectAgent

protected abstract EndServiceEvent selectAgent(Contact contact)
Begins the service of the contact contact by trying to assign it a free agent. The method must select an agent group with a free agent (or a specific free agent), start the service, and return the end-service event if the service was started, or null otherwise.

Parameters:
contact - the contact being routed to an agent.
Returns:
the end-service event representing the started service, or null if the contact could not be served immediately.

selectAgent

protected EndServiceEvent selectAgent(DequeueEvent dqEv,
                                      int numReroutingsDone)
Selects an agent for serving a queued contact in the context of rerouting. The event dqEv is used to represent the dequeued contact, while numReroutingsDone indicates the number of reroutings that has happened so far. The method should return the end-service event corresponding to the contact's new service by an agent, or null for the contact to stay in queue.

Parameters:
dqEv - the dequeue event representing the queued contact.
numReroutingsDone - the number of preceding reroutings.
Returns:
the end-service event, or null.

selectWaitingQueue

protected abstract DequeueEvent selectWaitingQueue(Contact contact)
Selects a waiting queue and puts the contact contact into it. Returns the dequeue event if the contact could be queued, or null otherwise.

Parameters:
contact - the contact being queued.
Returns:
the dequeue event representing the queued contact, or null if the contact could not be queued.

selectWaitingQueue

protected DequeueEvent selectWaitingQueue(DequeueEvent dqEv,
                                          int numReroutingsDone)
Selects a waiting queue for a queued contact in the context of rerouting. The event dqEv is used to represent the queued contact, while numReroutingsDone indicates the number of reroutings that has happened so far. The method should return the dequeue event corresponding to the contact's new queue, or null if the contact is required to leave the system. If no transfer of queue is required, this method should return dqEv. If a transfer occurs, one can use the dqTypeRet field to store the dequeue type of the contact leaving the queue.

Parameters:
dqEv - the dequeue event representing the queued contact.
numReroutingsDone - the number of preceding reroutings.
Returns:
the dequeue event, or null.

checkFreeAgents

protected boolean checkFreeAgents(AgentGroup group,
                                  Agent agent)
This method is called when the agent agent in agent group group becomes free. If the given agent is null, the method assumes that one or more arbitrary agents in the group became free. The method must select a contact to be transferred to the free agent. The selected contacts come from waiting queues, and must be removed from the queues with dequeue type DEQUEUETYPE_BEGINSERVICE before they are transferred to agents. The method returns true if and only if at least one free agent could be made busy.

The default implementation calls selectContact(AgentGroup,Agent) to get a new dequeue event representing the removed contact, extracts the contact, and routes it to an agent, until group has no more free agent.

Parameters:
group - the affected agent group.
agent - the agent having ended its service.
Returns:
true if some free agents became busy, false otherwise.

selectContact

protected DequeueEvent selectContact(AgentGroup group,
                                     Agent agent)
Returns a dequeue event representing a queued contact to be served by the agent agent in agent group group. If agent is null, the method must return a contact that can be served by any agent in the group. If no contact is available, this method returns null. The selected contacts come from waiting queues attached to the router. Before the selected contact is returned, it must be removed from its queue with dequeue type DEQUEUETYPE_BEGINSERVICE, e.g., by using queue.removeFirst (DEQUEUETYPE_BEGINSERVICE), or queue.remove (ev, DEQUEUETYPE_BEGINSERVICE), etc.

Generally, it is sufficient to override this method instead of checkFreeAgents(AgentGroup,Agent). One can override checkFreeAgents(AgentGroup,Agent) to improve efficiency when looking for contacts in the same waiting queue. This method is not abstract and returns null by default in order to allow checkFreeAgents(AgentGroup,Agent) to be overridden without implementing this method.

Parameters:
group - the affected agent group.
agent - the agent having ended its service.
Returns:
the dequeue event representing the contact being selected.

selectContact

protected DequeueEvent selectContact(Agent agent,
                                     int numReroutingsDone)
Selects a new contact for the agent agent, in the context of rerouting.

Parameters:
agent - the affected agent.
numReroutingsDone - the number of preceding reroutings.
Returns:
the selected contact, or null.

checkWaitingQueues

protected abstract void checkWaitingQueues(AgentGroup group)
This method is called when the agent group group contains no more online agents, i.e., AgentGroup.getNumAgents() returns 0. It must check each waiting queue accessible for agents in this group to determine if they need to be cleared. A queue is cleared if no agent, whether free or busy, is available to serve any contact in it.

Parameters:
group - the agent group with no more agents.

getReroutingDelay

protected double getReroutingDelay(DequeueEvent dqEv,
                                   int numReroutingsDone)
Returns the delay, in simulation time units, after which a queued contact should be rerouted. The value of numReroutingsDone gives the number of preceding reroutings, and dqEv is the dequeue event. If this delay is negative, infinite, or NaN, no rerouting happens for the contact. numReroutings will be -1 when this method is called at the time the contact is queued. By default, this method returns Double.POSITIVE_INFINITY.

Parameters:
dqEv - the dequeue event representing the queued contact.
numReroutingsDone - the number of reroutings so far.
Returns:
the rerouting delay.

getReroutingDelay

protected double getReroutingDelay(Agent agent,
                                   int numReroutingsDone)
Returns the delay, in simulation time units, after which an agent agent should try a new time to get a contact to serve. If no rerouting should happen, the returned delay must be negative or NaN. numReroutings will be -1 when this method is called at the end of a service. By default, this method returns Double.POSITIVE_INFINITY.

Parameters:
agent - the idle agent, or null.
numReroutingsDone - the number of previous reroutings for the agent.
Returns:
the rerouting delay.

beginService

protected void beginService(EndServiceEvent ev)
This method is called when the service of a contact, represented by the event ev, begins. By default, this method does nothing.

Parameters:
ev - the end-service event.

endContact

protected void endContact(EndServiceEvent ev)
This method is called when the communication between a contact and an agent is finished. By default, it calls exitServed(EndServiceEvent).

Parameters:
ev - the end-service event.

endService

protected void endService(EndServiceEvent ev)
This method is called when the service (communication and after-contact work) of a contact in an agent group has ended. By default, this does nothing.

Parameters:
ev - the end-service event.

enqueued

protected void enqueued(DequeueEvent ev)
This method is called when a contact is enqueued, ev representing the dequeue event. By default, this method does nothing.

Parameters:
ev - the dequeue event.

dequeued

protected void dequeued(DequeueEvent ev)
This method is called when a contact leaves a waiting queue, ev representing the corresponding dequeue event. By default, for any effective dequeue type other than 0, this calls exitDequeued(DequeueEvent). This method should not notify an exiting contact for a 0 dequeue type since it is reserved for queued and served contacts.

Parameters:
ev - the dequeue event.

formatWaitingQueues

public String formatWaitingQueues()
Formats the connected waiting queues as a string. For each queue slot, the returned string contains a line with the text Waiting queue q: followed by the queue's toString result. If no queue is connected to the slot, undefined is used as the waiting queue descriptor.

Returns:
the waiting queues of the router.

formatAgentGroups

public String formatAgentGroups()
Formats the connected agent groups as a string. For each group slot, the returned string contains a line with the text Agent group i: followed by the group's toString result. If no group is connected to the slot, undefined is used as the agent group descriptor.

Returns:
the agent groups of the router.

getWaitingQueueListener

public WaitingQueueListener getWaitingQueueListener()
Returns the waiting-queue listener registered with each waiting queue connected to this router. Obtaining this listener can be useful to replace it, in the list of listeners of a waiting queue, by a wrapper executing code before or after some events.

Returns:
the waiting-queue listener registered with each waiting queue.

getAgentGroupListener

public AgentGroupListener getAgentGroupListener()
Returns the agent-group listener registered with each agent group connected to this router. Obtaining this listener can be useful to replace it, in the list of listeners of an agent group, by a wrapper executing code before or after some events.

Returns:
the agent-group listener registered with each agent group.

getDescription

public String getDescription()

toString

public String toString()
Overrides:
toString in class Object

toLongString

public String toLongString()
Returns a string representation of detailed information about the router. This returns a string representation of each associated waiting queue and agent group and routing policies. For a short, one-line description, toString() should be used.

Returns:
a string representation of detailed information about the router.

ContactCenters
V. 0.9.9.

To submit a bug or ask questions, send an e-mail to Richard Simard.