Hey guys,
Recently made a user account, but been using Perl for a while and always come here for help. I am currently working on a novelty project for myself mostly where I am using the Asterisk AMI to read events and essentially create an ASCII/Perl based contact center. Most of this is going well, but I noticed something very odd while debugging earlier today. I am using threads as well as threads shared for the event parsing/main hash updating and I can't tell exactly what happened here. The steps that produce the data I am going to paste are as follows:
1). Event is read from the Asterisk AMI socket as an array:
while (1){
my @event = $astman->read_response;
chomp(@event);
2). It is then categorized/sanitized in a series of essentially inconsequential conditionals and is converted into a hash for easier parsing (at least by my current method) later:
lock(%queue_changes);
$event_id = int(rand(25000));
%type = &event_hasher(\@event);
event_hasher:
sub event_hasher{
my @cur_event = @{$_[0]};
my %event_hash;
foreach(@cur_event){
$_ =~ s/://g;
my @place_holder = split / /, $_;
$event_hash{$place_holder[0]} = $place_holder[1];
}
return %event_hash;
}
3). It is then put in a shared hash which consists of changes and is then read by the main thread which will update the changes:
$queue_changes{$event_id} = %type;
It seems that somewhere between the event being "hashed" and the newly "hashed" event being put into the hash of changes, some of the event hash keys were duplicated (at least according to Data::Dumper) as you can see below (removing some personal details):
Initial Event:
Sat Jan 9 21:10:50 2016
1452391850.044984517
Event:
$VAR1 = [
'Event: QueueMemberStatus',
'Privilege: agent,all',
'Queue: test-q',
'Location: SIP/EXTENSION-XXXX',
'MemberName: SIP/EXTENSION-XXXX',
'Membership: dynamic',
'Penalty: 0',
'CallsTaken: 1',
'LastCall: 1452391850',
'Status: 1',
'Paused: 0'
];
"Hashed" Event:
Sat Jan 9 21:10:52 2016
1452391852.284037579
Hashed Version: $VAR1 = {
'Status' => '1',
'Queue' => 'test-q',
'LastCall' => '1452391850',
'CallsTaken' => '1',
'MemberName' => 'SIP/EXTENSION-XXXX',
'Location' => 'SIP/EXTENSION-XXXX',
'Event' => 'QueueMemberStatus',
'Privilege' => 'agent,all',
'Paused' => '0',
'Membership' => 'dynamic'
};
"Queue Changes" Hash right after this event is added:
Queue Changes after Event Hashed:
$VAR1 = {
'9555' => {
'Event' => 'QueueMemberStatus',
'Privilege' => 'agent,all',
'Status' => '1',
'Queue' => 'test-q',
'Membership' => 'dynamic',
'Paused' => '0',
'MemberName' => 'SIP/EXTENSION-XXXX',
'CallsTaken' => '1',
'LastCall' => '1452391850',
'Location' => 'SIP/EXTENSION-XXXX'
}
};
This is where stuff get a little weird, this would be the same variable from the perspective of the main thread, right after is detected a change to the "Queue Changes" hash and went to update the main hash of agents:
Sat Jan 9 21:10:52 2016
1452391852.286708251
About to make Change:
$VAR1 = {
'9555' => {
'Event' => 'QueueMemberStatus',
'Queue' => 'test-q',
'MemberName' => 'SIP/EXTENSION-XXXX',
'LastCall' => '1452391850',
'Event' => 'QueueMemberStatus',
'Privilege' => 'agent,all',
'Status' => '1',
'Queue' => 'test-q',
'Membership' => 'dynamic',
'Paused' => '0',
'MemberName' => 'SIP/EXTENSION-XXXX',
'CallsTaken' => '1',
'LastCall' => '1452391850',
'Location' => 'SIP/EXTENSION-XXXX'
}
};
You can see there are multiple duplicate keys here and I wasn't sure if this was just Data::Dumper printing things out weird as this is a shared variable, or it was actually like this. Is this possible in Perl? I assumed that if it were to happen the "second" key/value pair would overwrite the first. Could this be caused by the use of a shared variable that is being update in one thread and read in another? (I am using locks when reading and writing to the variable). Just wanted to see if anyone had any insight in to what could be going on here. Also, if needed:
perl -v
This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
Copyright 1987-2009, Larry Wall
Perl may be copied only under the terms of either the Artistic License
+ or the
GNU General Public License, which may be found in the Perl 5 source ki
+t.
Complete documentation for Perl, including FAQ lists, should be found
+on
this system using "man perl" or "perldoc perl". If you have access to
+ the
Internet, point your browser at http://www.perl.org/, the Perl Home Pa
+ge.
Thanks!