Fix handling of extra_query_params in Business::OnlinePayment wrapper.
[interchange.git] / code / UserTag / child-process.tag
1 # Copyright 2008 Interchange Development Group and others
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.  See the LICENSE file for details.
7
8 # $Id: child-process.tag,v 1.3 2009-01-08 12:05:16 markj Exp $
9
10 UserTag child-process addAttr
11 UserTag child-process HasEndTag
12 UserTag child-process NoReparse 0
13 UserTag child-process Interpolate 0
14 UserTag child-process Version $Revision: 1.3 $
15 UserTag child-process Documentation <<EOD
16
17 =head1 NAME
18
19 child_process - Execute ITL code in a forked child process
20
21 =head1 SYNOPSIS
22
23 [child-process] ... ITL ... [/child-process]
24
25 =head1 DESCRIPTION
26
27 Runs Interchange markup code in a forked child process.
28 Useful for off-loading processes that take a relatively long time to complete.
29
30 Has no effect if the body is empty or contains only whitespace.
31
32 Options are:
33
34 =over 4
35
36 =item filename
37
38 File name relative to catalog directory to file where output from forked
39 process should be stored.
40
41 =item label
42
43 Optional descriptive label for this process that will be put in the operating
44 system process list. Default is "child-process tag".
45
46 =item notifyname
47
48 File name relative to catalog directory where a file of zero length will
49 be created if the file in option 'filename' is created successfully.
50
51 This empty file could be used for notification purposes, e.g. as an
52 indicator that the child process has delivered its output. When placed
53 in web docroot space one could poll for the existence of this file and
54 when it exists bounce to a page that will display the results.
55
56 =back
57
58 =head1 EXAMPLES
59
60  This is the parent process.
61
62  Child process starts here.
63  [child-process filename="tmp/report_[time]%Y%m%d%H%M%S[/time].txt"]
64  [query
65      list=1
66      sql="
67          ... some long-running SQL query ...
68      "
69  ][sql-line]
70  [/query]
71  [/child-process]
72  Child process ends here.
73
74  Some more parent stuff....
75
76 =head1 AUTHORS
77
78 Ton Verhagen <tverhagen@alamerce.nl>
79
80 Jon Jensen <jon@endpoint.com>
81
82
83 =cut
84
85 EOD
86 UserTag child-process Routine <<EOR
87
88 use POSIX ();
89
90 sub {
91     my ($opt, $body) = @_;
92     use vars qw/ $Tag /;
93
94     return unless defined($body) and $body =~ /\S/;
95
96     defined(my $kid = fork) or die "Cannot fork: $!\n";
97     if ($kid) {
98         waitpid($kid, 0);
99         return;
100     }
101     else {
102
103         Vend::Server::sever_database();
104
105         defined (my $grandkid = fork) or die "Kid cannot fork: $!\n";
106         exit if $grandkid;
107
108         Vend::Server::cleanup_for_exec();
109
110         # Disconnect from parent's terminal
111         POSIX::setsid() or die "Can't start a new session: $!\n";
112
113         defined $opt->{label} or $opt->{label} = 'child-process tag';
114         Vend::Server::set_process_name($opt->{label});
115
116         my $output = interpolate_html($body, 1);
117
118         my $filename = $opt->{filename};
119         if (defined($filename) and length($filename)) {
120             $filename = $Tag->filter('filesafe', $filename);
121             my $status = $Tag->write_relative_file($filename, $$output);
122
123             my $notifyname = $opt->{notifyname};
124             if ($status and defined($notifyname) and length($notifyname)) {
125                 $notifyname = $Tag->filter('filesafe', $notifyname);
126                 $Tag->write_relative_file($notifyname, $opt, '');
127             }
128         }
129
130         exit;
131     }
132 }
133 EOR