<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body text="#000000" bgcolor="#FFFFFF">
(PHP 5.33, AMQP protocol 0-9-1, librabbitmq 0.0.1, phpamqp 1.0.9)<span
style="color: rgb(0, 0, 0); font-family: sans-serif; font-size:
12px; font-style: normal; font-variant: normal; font-weight: bold;
letter-spacing: normal; line-height: normal; orphans: auto;
text-align: center; text-indent: 0px; text-transform: none;
white-space: normal; widows: auto; word-spacing: 0px;
-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;
background-color: rgb(153, 153, 204); display: inline !important;
float: none;"></span><br>
<br>
I'm having trouble figuring out how to gracefully shut down a
blocking PHP consumer.<br>
<br>
The context of this problem is that we would like to create a script
that forks many consumer children based on a configuration file.
That script will then monitor its children and restart them should
any fail. We would also like to be able to kill this parent script
and have it stop and kill its children and then exit.<br>
<br>
Our preference is to use consume() rather than get() if possible.<br>
<br>
The problem we're having is how to get a signal to the child
processes to get them to stop consuming.<br>
<br>
A very simple example script (with connection info removed):<br>
<br>
<?php<br>
// so we can catch system calls... <br>
declare(ticks=1); <br>
<br>
pcntl_signal(SIGTERM, array('RunControl', 'sysCalls')); <br>
pcntl_signal(SIGHUP, array('RunControl', 'sysCalls')); <br>
pcntl_signal(SIGUSR1, array('RunControl', 'sysCalls')); <br>
<br>
<br>
class RunControl<br>
{<br>
static $alive = true;<br>
<br>
// catch system calls<br>
function sysCalls($signal) <br>
{ <br>
print "Got signal to die\n";<br>
}<br>
}<br>
<br>
function consume($message, $queue)<br>
{<br>
print "Got a message!\n";<br>
$queue->ack($message->getDeliveryTag());<br>
}<br>
<br>
<br>
$connection = new AMQPConnection($connectionInfo);<br>
$connection->connect();<br>
<br>
$channel = new AMQPChannel($connection);<br>
$queue = new AMQPQueue($channel);<br>
<br>
$queue->setName('my_queue');<br>
<br>
$queue->consume('consume');<br>
?><br>
<br>
If I run this script, the consumer will happily consume messages.
However, executing a kill command on its pid does not cause the "Got
signal to die" message to print.<br>
<br>
I have tried using $queue->cancel() in many different
configurations (within the same script, in another script, with a
consumer tag, without), but it doesn't seem to do anything.<br>
<br>
I tried the workaround described here: <a
href="http://blog.andrewrose.co.uk/2008/02/php-getting-signals-through-to-blocking.html">http://blog.andrewrose.co.uk/2008/02/php-getting-signals-through-to-blocking.html</a>
and it resulted in a whole bunch of "interrupted system call"
exceptions.<br>
<br>
Does anyone have any suggestions for how I can get my consumer to
exit gracefully? Thanks.<br>
<br>
- Colleen<br>
<br>
<br>
</body>
</html>