FuelPHP1.8でredisにコマンド発行すると時々無限ループする件
起きる条件
- oilで作ったタスクをデーモン化して常時起動させている場合
- redisとの接続が常時接続である場合
上記条件のときにredisの接続しているソケット接続が何らかの原因によって閉じられた場合に、fwriteの戻り値$fwriteに0が返り無限ループになります
fuel/core/classes/redis/db.php
public function execute()
{
// open a Redis connection and execute the queued commands
foreach ($this->queue as $command)
{
for ($written = 0; $written < strlen($command); $written += $fwrite)
{
$fwrite = fwrite($this->connection, substr($command, $written));
if ($fwrite === false )
{
throw new \RedisException('Failed to write entire command to stream');
}
}
}
※ このコードは昔からある(1.3から存在)みたいで、おそらく通常のmod_phpからの実行ではmax_execution_timeで強制終了されるのでそれほど問題無いのだとおもいます。
ログ
以下のログが永遠に出ます。
fwrite(): send of 58 bytes failed with errno=32 Broken pipe in fuel/core/classes/redis/db.php on line 148
修正箇所
public function execute()
{
// open a Redis connection and execute the queued commands
foreach ($this->queue as $command)
{
for ($written = 0; $written < strlen($command); $written += $fwrite)
{
$fwrite = fwrite($this->connection, substr($command, $written));
if ($fwrite === false || $fwrite <= 0)
{
throw new \RedisException('Failed to write entire command to stream');
}
}
}
1.9の開発リポジトリにパッチ送って取り込んでもらえたので次期バージョンでは直ると思います。