Asterisk RealTime Queue
Asterisk RealTime Queues
The queue application supports dynamic realtime. With dynamic realtime, the queue definition and member list will be reloaded each time a caller joins the queue. Thus queues can be updated in the database and the changes will be immediately visible without the need for an explicit reload.
It is possible to mix statically and dynamically defined queues. If a queue is defined in both static and dynamic realtime, the static version is used. The agent login feature currently only works for static queues though (a similar effect can be achieved with dynamic queues simply by inserting an appropriate row for a new member).
Extconfig.conf Setup
Add the following lines (changing of family names isn't allowed):queues => mysql,asterisk,queue_table
queue_members => mysql,asterisk,queue_member_table
This example uses MySQL, but other realtime drivers (eg. ODBC) also work. The database containing the queue definitions is asterisk in this example, and the tables are called queue_table and queue_member_table.
Database Tables
Here are suitable MySQL table definitions for realtime queues. First the table defining each queue, with one row per queue.
CREATE TABLE queue_table (
name VARCHAR(128) PRIMARY KEY,
musiconhold VARCHAR(128),
announce VARCHAR(128),
context VARCHAR(128),
timeout INT(11),
monitor_join BOOL,
monitor_format VARCHAR(128),
queue_youarenext VARCHAR(128),
queue_thereare VARCHAR(128),
queue_callswaiting VARCHAR(128),
queue_holdtime VARCHAR(128),
queue_minutes VARCHAR(128),
queue_seconds VARCHAR(128),
queue_lessthan VARCHAR(128),
queue_thankyou VARCHAR(128),
queue_reporthold VARCHAR(128),
announce_frequency INT(11),
announce_round_seconds INT(11),
announce_holdtime VARCHAR(128),
retry INT(11),
wrapuptime INT(11),
maxlen INT(11),
servicelevel INT(11),
strategy VARCHAR(128),
joinempty VARCHAR(128),
leavewhenempty VARCHAR(128),
eventmemberstatus BOOL,
eventwhencalled BOOL,
reportholdtime BOOL,
memberdelay INT(11),
weight INT(11),
timeoutrestart BOOL,
periodic_announce VARCHAR(50),
periodic_announce_frequency INT(11),
ringinuse BOOL
);
name VARCHAR(128) PRIMARY KEY,
musiconhold VARCHAR(128),
announce VARCHAR(128),
context VARCHAR(128),
timeout INT(11),
monitor_join BOOL,
monitor_format VARCHAR(128),
queue_youarenext VARCHAR(128),
queue_thereare VARCHAR(128),
queue_callswaiting VARCHAR(128),
queue_holdtime VARCHAR(128),
queue_minutes VARCHAR(128),
queue_seconds VARCHAR(128),
queue_lessthan VARCHAR(128),
queue_thankyou VARCHAR(128),
queue_reporthold VARCHAR(128),
announce_frequency INT(11),
announce_round_seconds INT(11),
announce_holdtime VARCHAR(128),
retry INT(11),
wrapuptime INT(11),
maxlen INT(11),
servicelevel INT(11),
strategy VARCHAR(128),
joinempty VARCHAR(128),
leavewhenempty VARCHAR(128),
eventmemberstatus BOOL,
eventwhencalled BOOL,
reportholdtime BOOL,
memberdelay INT(11),
weight INT(11),
timeoutrestart BOOL,
periodic_announce VARCHAR(50),
periodic_announce_frequency INT(11),
ringinuse BOOL
);
This table has a column for each possible queue parameter. Except for the mandatory name column, all columns are optional, and only the columns actually used need be included. Likewise, more columns may be added if the queue application is later extended with more parameters. A NULL value for a column indicates an unset parameter.
If you are using mysql 3.2.5X or lower the BOOL don't work so you have to simulate the behavior of the boolean with a tinyint(1) where 0 = false and 1 = true. that will change the structure to
CREATE TABLE queue_table (
name VARCHAR(128) PRIMARY KEY,
musiconhold VARCHAR(128),
announce VARCHAR(128),
context VARCHAR(128),
timeout INT(11),
monitor_join tinyint(1),
monitor_format VARCHAR(128),
queue_youarenext VARCHAR(128),
queue_thereare VARCHAR(128),
queue_callswaiting VARCHAR(128),
queue_holdtime VARCHAR(128),
queue_minutes VARCHAR(128),
queue_seconds VARCHAR(128),
queue_lessthan VARCHAR(128),
queue_thankyou VARCHAR(128),
queue_reporthold VARCHAR(128),
announce_frequency INT(11),
announce_round_seconds INT(11),
announce_holdtime VARCHAR(128),
retry INT(11),
wrapuptime INT(11),
maxlen INT(11),
servicelevel INT(11),
strategy VARCHAR(128),
joinempty VARCHAR(128),
leavewhenempty VARCHAR(128),
eventmemberstatus tinyint(1),
eventwhencalled tinyint(1),
reportholdtime tinyint(1),
memberdelay INT(11),
weight INT(11),
timeoutrestart tinyint(1),
ringinuse tinyint(1)
);
name VARCHAR(128) PRIMARY KEY,
musiconhold VARCHAR(128),
announce VARCHAR(128),
context VARCHAR(128),
timeout INT(11),
monitor_join tinyint(1),
monitor_format VARCHAR(128),
queue_youarenext VARCHAR(128),
queue_thereare VARCHAR(128),
queue_callswaiting VARCHAR(128),
queue_holdtime VARCHAR(128),
queue_minutes VARCHAR(128),
queue_seconds VARCHAR(128),
queue_lessthan VARCHAR(128),
queue_thankyou VARCHAR(128),
queue_reporthold VARCHAR(128),
announce_frequency INT(11),
announce_round_seconds INT(11),
announce_holdtime VARCHAR(128),
retry INT(11),
wrapuptime INT(11),
maxlen INT(11),
servicelevel INT(11),
strategy VARCHAR(128),
joinempty VARCHAR(128),
leavewhenempty VARCHAR(128),
eventmemberstatus tinyint(1),
eventwhencalled tinyint(1),
reportholdtime tinyint(1),
memberdelay INT(11),
weight INT(11),
timeoutrestart tinyint(1),
ringinuse tinyint(1)
);
As a convenience, it is permitted (but not required) to use underscore "_" instead of dash "-" in column names, since this is easier to handle in SQL.
The member table has a row for each member in a queue:
CREATE TABLE queue_member_table (
uniqueid INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
membername varchar(40),
queue_name varchar(128),
interface varchar(128),
penalty INT(11),
paused BOOL,
UNIQUE KEY queue_interface (queue_name, interface)
);
uniqueid INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
membername varchar(40),
queue_name varchar(128),
interface varchar(128),
penalty INT(11),
paused BOOL,
UNIQUE KEY queue_interface (queue_name, interface)
);
One may add a foreign key from queue_name in the member table to name in the queue table, if so desired.
The values that go in the table for the fields "interface" and "penalty" are for example as shown below
interface= Agent/1112
penalty = 2
Set the [general] context in the queues.conf file
It was previously stated here that you need to add realtime_family in queues.conf, but you actually don't need to. App_queue always uses family names "queues" and "queue_members"
Using it
Define a queue by inserting a row in the queue table, and add members by inserting rows in the queue member table. The new queue should be immediately available for joining with the Queue() application command.
Note: realtime queues and queue members will be re-read when using Queue application, QUEUE_MEMBER_COUNT function, or CLI command "queue show QUEUENAME". Note that "queue show" does NOT re-load the queue data and will display cached information.
Further development
The mantis bug describing the implementation of realtime queue is bug 4037. This bug includes some discussion on how to extend dynamic queues to also work with the member login feature.
See also
- Asterisk config queues.conf
- Asterisk cmd Queue
- Asterisk call queues
- OrderlyQ - Extension to Asterisk Queues that lets callers hang up, then call back without losing their place.
- OrderlyStats - FREE Dedicated Real Time Call Centre Management and Statistics Package.


Comments
333Realtime SIP agent locate across server
333Can please any one tell me what other data will be inserted in realtime queue table
Thanks
333How to create realtime agents
333Where is periodic-announce capability?
333Points to note about RealTime queues...
1. The database is only queried when someone joins a queue, If I join a queue with two members configured in the members table and a member is removed from the table while I'm in the queue I won't know that they have been removed until another caller joins the queue and so will continue calling both members until the other caller joins the queue.
2. Even with 'persistentmembers = yes' in queues.conf queue member status is NOT kept across restarts or reloads :(
3. If Asterisk is reloaded while I'm waiting in a queue the queue I'm in becomes orphaned. I continue calling the members that were present when Asterisk was reloaded but new callers will join a parallel queue which causes congestion when both queues try to call out to the same member and means the number of calls waiting in the queue are inaccurate.
IMHO issue 1 can be solved by re-querying the database at regular intervals dependant on the calling strategy used. I believe issues 2 & 3 are bugs and require fixing to bring them in line with people's expectations of the queue functionality.
333Realtime needs reload
333Really Realtime ?
Tested on Asterisk 1.2.4
Example:
I changed the strategy field in the sql table queue_table.
The behavior was that until a reload or complete Asterisk restart happened,
the old setting for strategy was used.
Any Ideas ?