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!

In reply to Ending up with duplicate keys in a hash?\ by coffeemaster1

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.