2013-12-17 86 views
2

我有一個代碼如下:執行星號回調的Perl命令?

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 } 

我使用Asterisk::AMI模塊,用於從星號AMI獲取信息。 do_leave子每當有人離開會議時被調用。我的問題是get_valuedo_leave的所有語句後執行的回調。 如何在第10行之前執行get_value回調。變量\$join_idsend_action是回調的第三個參數。在sql語句之前,我需要$join_id變量。

+0

是'send_id'保證調用'get_value'回調?所以你只是想在更新數據庫之前確保回調已經被執行了?在這種情況下,我會立刻爲您準備好*期貨*的解決方案。 – amon

+0

@amon yes send_action將會執行'get_value'回調,但是在數據庫更新之後,它在執行之前也不會做任何事情,因爲'$ sth-> execute($ join_id);'needs'join_id'。 –

回答

1

我沒有使用過Asterisk :: AMI,但我認爲send_action方法採用回調方法的原因是結果異步返回。你無法保證需要多長時間。

一個快速簡便的解決方案是將回調函數像這裏面的數據庫更新:我已經使用匿名子

sub do_leave { 

    my ($asterisk, $event) = @_; 
    my $get_value = sub { 
    my ($ast, $resp, $ref_join_id) = @_; 
    for my $key (keys %$resp) { 
     if ($key eq "PARSED") { 
      my $ref_join_id = $resp->{$key}{"Value"}; 
      my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?"; 
      my $sth = $dbh->prepare($sql); 
      $sth->execute($join_id); 
     } 
    } 
    }; 

    my $id = $astman->send_action({ Action => 'Getvar', 
            Variable => 'join_id', 
            Channel => $event->{'Channel'}, 
           }, $get_value); 

} 

通知,分配給一個變量,這樣可以讓大家分享變數在do_leave子外部和回調子部分之間(這稱爲閉包)。但是在這種情況下,可能不需要,因爲沒有共享變量。

+0

謝謝。我真的不知道把數據庫更新放在回調函數中。 –

2

對於最小的變化你的腳本,

sub do_leave { 

    my ($asterisk, $event) = @_; 
    my $join_id; 

    my $sub = sub { 
    get_value(@_); 
    say "join_id is: $join_id"; 

    my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?"; 
    my $sth = $dbh->prepare($sql); 
    $sth->execute($join_id); 
    }; 
    my $id = $astman->send_action({ Action => 'Getvar', 
            Variable => 'join_id', 
            Channel => $event->{'Channel'}, 
           }, $sub, undef, \$join_id); 
    # sleep(2); 
}