I have a code as follow:
1 sub do_leave {
2
3 my ($asterisk, $event) = @_;
4 my $join_id;
5 my $id = $astman->send_action({ Action => 'Getvar',
6 Variable => 'join_id',
7 Channel => $event->{'Channel'},
8 }, \&get_value, undef, \$join_id);
9
10 sleep(2);
11 say "join_id is: $join_id";
12
13 my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?";
14 my $sth = $dbh->prepare($sql);
15 $sth->execute($join_id);
16 }
17
18 sub get_value {
19 my ($ast, $resp, $ref_join_id) = @_;
20 for my $key (keys %$resp) {
21 if ($key eq "PARSED") {
22 $$ref_join_id = $resp->{$key}{"Value"};
23 }
24 }
25 }
I'm using Asterisk::AMI module for getting information from asterisk AMI.
the do_leave
sub is called whenever someone leaves the conference. My question is get_value
callback executed after all statements in do_leave
.
How can i make get_value
callback executed before line 10. Variable \$join_id
in send_action
is third argument to the callback. I need $join_id
variable before sql statements.
I've not worked with Asterisk::AMI, but I assume that the reason the send_action method takes a callback method is that the result comes back asynchronously. You can't guarantee how long that will take.
A quick and easy solution is to place the database update inside the callback function like this:
Notice that I have used an anonymous sub, assigned to a variable, which would allow you to share variables between the outer do_leave sub and the callback sub (this is called a closure). However in this case it is probably not needed since there are no shared variables.