Hi. I just want to make sure I understand this before doing something that might break things spectacularly for our users and customers :) We are using Asterisk 1.6.2.9 and my programming language of choice is Perl. I want, when a call comes in on someone's DDI number (which the person who dialled it can only possibly have obtained by dialling 1471 after we called them), to be able to look up the caller's details from one of our databases (where the number ought to be stored, because we already dialled it). Now, this search is going to take some time; so I'd like for the AGI script to fork a clone of itself, so the parent process can exit and the dialplan continue on to ring the person's phone, while the database lookup is done in the background (the script doesn't need to have any further contact with Asterisk -- it will initiate any necessary future communication via other channels). Is this the sort of thing I need? ########## begin code snippet ########## #!/usr/bin/perl -w use strict; use Asterisk::AGI; my $AGI = new Asterisk::AGI; my %params = $AGI->ReadParse(); $SIG{CHLD} = "IGNORE"; if (my $child_pid = fork) { # This is executed in the parent process exit; } elsif (defined $child_pid) { # This is executed in the child process close STDIN; close STDOUT; close STDERR; # Load some more modules and do some stuff # that will take a long time exit; } else { die "Could not fork: $!"; }; ########## end code snippet ########## Am I right in thinking I shouldn't have to worry about zombie processes, because the parent exits before the child and the init in modern Linux distros is smart enough to deal with orphaned processes itself? -- AJS Answers come *after* questions.
Am 13.04.2011 15:08, schrieb A J Stiles:> Hi. I just want to make sure I understand this before doing something that > might break things spectacularly for our users and customers :) > > We are using Asterisk 1.6.2.9 and my programming language of choice is Perl. > > I want, when a call comes in on someone's DDI number (which the person who > dialled it can only possibly have obtained by dialling 1471 after we called > them), to be able to look up the caller's details from one of our databases > (where the number ought to be stored, because we already dialled it). > > Now, this search is going to take some time; so I'd like for the AGI script to > fork a clone of itself, so the parent process can exit and the dialplan > continue on to ring the person's phone, while the database lookup is done in > the background (the script doesn't need to have any further contact with > Asterisk -- it will initiate any necessary future communication via other > channels). > > > Is this the sort of thing I need? > > ########## begin code snippet ########## > > #!/usr/bin/perl -w > use strict; > use Asterisk::AGI; > > my $AGI = new Asterisk::AGI; > my %params = $AGI->ReadParse(); > > $SIG{CHLD} = "IGNORE"; > > if (my $child_pid = fork) { > # This is executed in the parent process > exit; > } > elsif (defined $child_pid) { > # This is executed in the child process > > close STDIN; > close STDOUT; > close STDERR; > > # Load some more modules and do some stuff > # that will take a long time > > exit; > } > else { > die "Could not fork: $!"; > }; > > ########## end code snippet ########## > > Am I right in thinking I shouldn't have to worry about zombie processes, > because the parent exits before the child and the init in modern Linux > distros is smart enough to deal with orphaned processes itself? >It should work - I think. BUT I am not really sure what will happen, if the child process exits. The child works with a copy of all asterisk ressources given to it, when forking. So when the child dies, perhaps asterisk will do a hangup or continues in the dialplan for this process. I think, that could cause some unwanted results. You should try to write a daemon process which handles the database lookups or whataver while being totally independent of the atserisk process. This is a little bit more overhead for the communication between the astersk process (the call itself) and your lookup-daemon. But it would be more stable - for my point of view. -Thorsten-
On Wed, 13 Apr 2011, A J Stiles wrote:> I want, when a call comes in on someone's DDI number (which the person > who dialled it can only possibly have obtained by dialling 1471 after we > called them), to be able to look up the caller's details from one of our > databases (where the number ought to be stored, because we already > dialled it). > > Now, this search is going to take some time; so I'd like for the AGI > script to fork a clone of itself, so the parent process can exit and the > dialplan continue on to ring the person's phone, while the database > lookup is done in the background (the script doesn't need to have any > further contact with Asterisk -- it will initiate any necessary future > communication via other channels).I solved a similar problem with a multi-threaded AGI. I created a thread to play 'Please wait while we verify your card details' while the main program did the database look ups and sent the auth out to our card processor. By the time the prompt finished, I had the response back from the card processor so the 'wait' appeared to the caller to be instantaneous. -- Thanks in advance, ------------------------------------------------------------------------- Steve Edwards sedwards at sedwards.com Voice: +1-760-468-3867 PST Newline Fax: +1-760-731-3000
On Wednesday 13 April 2011 08:08:03 A J Stiles wrote:> Hi. I just want to make sure I understand this before doing something > that might break things spectacularly for our users and customers :) > > We are using Asterisk 1.6.2.9 and my programming language of choice is > Perl. > > I want, when a call comes in on someone's DDI number (which the person > who dialled it can only possibly have obtained by dialling 1471 after > we called them), to be able to look up the caller's details from one > of our databases (where the number ought to be stored, because we > already dialled it). > > Now, this search is going to take some time; so I'd like for the AGI > script to fork a clone of itself, so the parent process can exit and > the dialplan continue on to ring the person's phone, while the database > lookup is done in the background (the script doesn't need to have any > further contact with Asterisk -- it will initiate any necessary future > communication via other channels). > > > Is this the sort of thing I need? > > ########## begin code snippet ########## > > #!/usr/bin/perl -w > use strict; > use Asterisk::AGI; > > my $AGI = new Asterisk::AGI; > my %params = $AGI->ReadParse(); > > $SIG{CHLD} = "IGNORE"; > > if (my $child_pid = fork) { > # This is executed in the parent process > exit; > } > elsif (defined $child_pid) { > # This is executed in the child process > > close STDIN; > close STDOUT; > close STDERR; > > # Load some more modules and do some stuff > # that will take a long time > > exit; > } > else { > die "Could not fork: $!"; > }; > > ########## end code snippet ########## > > Am I right in thinking I shouldn't have to worry about zombie processes, > because the parent exits before the child and the init in modern Linux > distros is smart enough to deal with orphaned processes itself?Almost. You should also set a new session ID to ensure that the child gets a new processgroup. Otherwise, on some systems, it will still wait for the child to also exit). In Perl, this is accessible from the POSIX module, function setsid(). -- Tilghman
On Wednesday 13 Apr 2011, Thorsten G?llner wrote:> It should work - I think. BUT I am not really sure what will happen, if > the child process exits. The child works with a copy of all asterisk > ressources given to it, when forking. So when the child dies, perhaps > asterisk will do a hangup or continues in the dialplan for this process. > I think, that could cause some unwanted results.The parent exits immediately after the fork. The child begins by closing STDIN, STDOUT and STDERR; so once those handles are dropped, it ought to be completely separate from Asterisk.> You should try to write a daemon process which handles the database > lookups or whataver while being totally independent of the atserisk > process.I hadn't actually thought of doing it that way, but it makes sense. Still, the forking method seemed to work (i.e., the dialplan continues straight away) when I tested it with just a sleep in the child process (once I remembered to close STDIN, STDOUT and STDERR!) and I could not get a zombie when I thoroughly tested forking on my own desktop, so I'll give it a go and see what happens ..... -- AJS Answers come *after* questions.