Skip to content

Commit

Permalink
Merge pull request #8 from henriquemoody/handlers
Browse files Browse the repository at this point in the history
Centralize handlers for signals and PHP errors
  • Loading branch information
henriquemoody committed Nov 5, 2014
2 parents e37a7a5 + 956a0c2 commit f577748
Show file tree
Hide file tree
Showing 16 changed files with 163 additions and 56 deletions.
30 changes: 9 additions & 21 deletions src/Arara/Process/Child.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,33 +106,21 @@ public function kill()
*
* @return void
*/
protected function setTimeoutHandler(array $context)
protected function setHandlerAlarm(array $context)
{
$action = $this->action;
$control = $this->control;
$control->signal()->handle('alarm', function () use ($action, $control, $context) {
// @codeCoverageIgnoreStart
$context['finishTime'] = time();
$action->trigger(Action::EVENT_TIMEOUT, $control, $context);
$control->quit(3);
// @codeCoverageIgnoreEnd
});
$control->signal()->alarm($this->timeout);
$handler = new Handler\SignalAlarm($this->control, $this->action, $context);
$this->control->signal()->handle('alarm', $handler);
$this->control->signal()->alarm($this->timeout);
}

/**
* Overwrite default PHP error handler to throws exception when an error occurs.
*
* @return void
*/
protected function setPhpErrorHandler()
protected function setHandlerErrorException()
{
set_error_handler(
function ($severity, $message, $filename, $line) {
throw new ErrorException($message, 0, $severity, $filename, $line);
},
E_ALL & ~E_NOTICE
);
set_error_handler(new Handler\ErrorException(), E_ALL & ~E_NOTICE);
}

/**
Expand Down Expand Up @@ -196,12 +184,12 @@ public function start()

$context = array(
'processId' => $this->processId,
'startTime' => time(),
'timeout' => $this->timeout,
'startTime' => time(),
);

$this->setTimeoutHandler($context);
$this->setPhpErrorHandler();
$this->setHandlerAlarm($context);
$this->setHandlerErrorException();
$this->run($context);
restore_error_handler();
}
Expand Down
8 changes: 4 additions & 4 deletions src/Arara/Process/Control.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public function __construct()
{
$this->info = new Control\Info();
$this->signal = new Control\Signal();
$this->signal->handle('child', new Control\Signal\ChildHandler($this));
$this->signal->handle('interrupt', new Control\Signal\InterruptHandler($this));
$this->signal->handle('quit', new Control\Signal\QuitHandler($this));
$this->signal->handle('terminate', new Control\Signal\TerminateHandler($this));
$this->signal->handle('child', new Handler\SignalChild($this));
$this->signal->handle('interrupt', new Handler\SignalInterrupt($this));
$this->signal->handle('quit', new Handler\SignalQuit($this));
$this->signal->handle('terminate', new Handler\SignalTerminate($this));
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/Arara/Process/Handler/ErrorException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Arara\Process\Handler;

class ErrorException
{
public function __invoke($severity, $message, $filename, $line)
{
throw new \ErrorException($message, 0, $severity, $filename, $line);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

use Arara\Process\Control;

abstract class AbstractHandler
abstract class SignalAbstract
{
protected $control;

Expand Down
28 changes: 28 additions & 0 deletions src/Arara/Process/Handler/SignalAlarm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Arara\Process\Handler;

use Arara\Process\Action\Action;
use Arara\Process\Context;
use Arara\Process\Control;

class SignalAlarm extends SignalAbstract
{
protected $action;
protected $context;

public function __construct(Control $control, Action $action, array $context)
{
$this->action = $action;
$this->context = $context;

parent::__construct($control);
}

public function __invoke($signal)
{
$this->context['finishTime'] = time();
$this->action->trigger(Action::EVENT_TIMEOUT, $this->control, $this->context);
$this->control->quit(3);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

class ChildHandler extends AbstractHandler
class SignalChild extends SignalAbstract
{
public function __invoke($signal)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

class InterruptHandler extends AbstractHandler
class SignalInterrupt extends SignalAbstract
{
public function __invoke($signal)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

class QuitHandler extends AbstractHandler
class SignalQuit extends SignalAbstract
{
public function __invoke($signal)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

class TerminateHandler extends AbstractHandler
class SignalTerminate extends SignalAbstract
{
public function __invoke($signal)
{
Expand Down
21 changes: 21 additions & 0 deletions tests/Arara/Process/Handler/ErrorExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Arara\Process\Handler;

use Arara\Process\Control;

/**
* @covers Arara\Process\Handler\ErrorException
*/
class ErrorExceptionTest extends \TestCase
{
/**
* @expectedException ErrorException
* @expectedExceptionMessage Some message
*/
public function testShouldThrowsErrorExceptionWhenCalled()
{
$handler = new ErrorException();
$handler(E_ERROR, 'Some message', __FILE__, __LINE__);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

use Arara\Process\Control;

/**
* @covers Arara\Process\Control\Signal\AbstractHandler
* @covers Arara\Process\Handler\SignalAbstract
*/
class AbstractHandlerTest extends \TestCase
class SignalAbstractTest extends \TestCase
{
public function testShouldAcceptAnInstanceOfControlOnConstructor()
{
$control = new Control();
$handler = $this->getMockForAbstractClass('Arara\Process\Control\Signal\AbstractHandler', array($control));
$handler = $this->getMockForAbstractClass('Arara\Process\Handler\SignalAbstract', array($control));

$this->assertAttributeSame($control, 'control', $handler);
}
Expand Down
59 changes: 59 additions & 0 deletions tests/Arara/Process/Handler/SignalAlarmTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Arara\Process\Handler;

function time()
{
if ( isset($GLOBALS['time'])) {
return $GLOBALS['time'];
}

return \time();
}

use Arara\Process\Action\Action;

/**
* @covers Arara\Process\Handler\SignalAlarm
*/
class SignalAlarmTest extends \TestCase
{

const TIMESTAMP = 1230192830;

protected function init()
{
$GLOBALS['time'] = self::TIMESTAMP;
}

protected function finish()
{
unset($GLOBALS['time']);
}

public function testShouldHandleAlarm()
{
$control = $this
->getMockBuilder('Arara\Process\Control')
->setMethods(array('quit'))
->getMock();

$control
->expects($this->once())
->method('quit')
->with(3);

$action = $this
->getMockBuilder('Arara\Process\Action\Action')
->setMethods(array('execute', 'trigger'))
->getMock();

$action
->expects($this->once())
->method('trigger')
->with(Action::EVENT_TIMEOUT, $control, array('finishTime' => self::TIMESTAMP));

$handler = new SignalAlarm($control, $action, array());
$handler(SIGALRM);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

/**
* @covers Arara\Process\Control\Signal\ChildHandler
* @covers Arara\Process\Handler\SignalChild
*/
class ChildHandlerTest extends \TestCase
class SignalChildTest extends \TestCase
{
public function testShouldWaitChildrenFinish()
{
Expand All @@ -20,7 +20,7 @@ public function testShouldWaitChildrenFinish()
->with(0, (WNOHANG | WUNTRACED))
->will($this->returnValue(0));

$handler = new ChildHandler($control);
$handler = new SignalChild($control);
$handler(SIGCHLD);
}

Expand All @@ -37,7 +37,7 @@ public function testShouldTryToWaitUntilChildrenFinish()
->with(0, (WNOHANG | WUNTRACED))
->will($this->onConsecutiveCalls(999, 0));

$handler = new ChildHandler($control);
$handler = new SignalChild($control);
$handler(SIGCHLD);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

/**
* @covers Arara\Process\Control\Signal\InterruptHandler
* @covers Arara\Process\Handler\SignalInterrupt
*/
class InterruptHandlerTest extends \TestCase
class SignalInterruptTest extends \TestCase
{
public function testShouldExitAs3()
{
Expand All @@ -19,7 +19,7 @@ public function testShouldExitAs3()
->method('quit')
->with(3);

$handler = new InterruptHandler($control);
$handler = new SignalInterrupt($control);
$handler(SIGINT);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

/**
* @covers Arara\Process\Control\Signal\QuitHandler
* @covers Arara\Process\Handler\SignalQuit
*/
class QuitHandlerTest extends \TestCase
class SignalQuitTest extends \TestCase
{
public function testShouldExitAs4()
{
Expand All @@ -19,7 +19,7 @@ public function testShouldExitAs4()
->method('quit')
->with(4);

$handler = new QuitHandler($control);
$handler = new SignalQuit($control);
$handler(SIGQUIT);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

namespace Arara\Process\Control\Signal;
namespace Arara\Process\Handler;

/**
* @covers Arara\Process\Control\Signal\TerminateHandler
* @covers Arara\Process\Handler\SignalTerminate
*/
class TerminateHandlerTest extends \TestCase
class SignalTerminateTest extends \TestCase
{
public function testShouldExitAs0()
{
Expand All @@ -19,7 +19,7 @@ public function testShouldExitAs0()
->method('quit')
->with(0);

$handler = new TerminateHandler($control);
$handler = new SignalTerminate($control);
$handler(SIGTERM);
}
}

0 comments on commit f577748

Please sign in to comment.