Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context Done & Timeout #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use Packaged\Config\ConfigProviderInterface;
use Packaged\Config\Provider\ConfigProvider;
use Packaged\Context\Events\ContextDoneEvent;
use Packaged\Event\Channel\Channel;
use Packaged\Helpers\System;
use Packaged\Http\Cookies\CookieJar;
Expand All @@ -25,13 +26,18 @@ class Context implements ContextAware
const ENV_STAGE = 'stage';
const ENV_PROD = 'prod';

const DONE_DESTRUCT = 1;
const DONE_MANUAL = 2;
const DONE_TIMEOUT = 3;

protected $_projectRoot;
protected $_env;
protected $_cfg;
protected $_meta;
protected $_routeData;

private $_id;
private $_done;
private $_events;
private $_request;
private $_cookieJar;
Expand Down Expand Up @@ -253,4 +259,47 @@ public function hasContext(): bool
return true;
}

public function withTimeout(int $duration)
{
new ContextTimeout($this, $duration);
return $this;
}

/**
* Mark the context as done, and trigger the done event
*
* @param $reason
*
* @return bool
* @throws \Exception
*/
public function done($reason = ContextDoneEvent::RSN_TRIGGER)
{
if($this->_done === null)
{
$this->_done = $reason;
$this->events()->trigger(new ContextDoneEvent($reason));
}
return true;
}

public function isDone(): bool
{
return $this->_done !== null;
}

public function __destruct()
{
if($this->_events && !$this->_done)
{
try
{
$this->done(ContextDoneEvent::RSN_DESTRUCT);
}
catch(\Exception $e)
{
}
}
}

}
52 changes: 52 additions & 0 deletions src/ContextTimeout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
namespace Packaged\Context;

use Packaged\Context\Events\ContextDoneEvent;
use Packaged\Context\Events\ContextTimeoutEvent;

class ContextTimeout
{
private $_ctx;
private $_duration;
private $_expiry;

public function __construct(Context $context, $duration = 30)
{
$this->_ctx = $context;
$this->_ctx->events()->listen(ContextDoneEvent::TYPE, [$this, 'onComplete']);
$this->_duration = $duration;
$this->_expiry = time() + $duration;
register_tick_function([$this, 'onTick']);
}

protected function _tick()
{
if($this->_expiry <= time())
{
$this->_ctx->events()->trigger(new ContextTimeoutEvent($this->_duration, time()));
$this->_ctx->done(ContextDoneEvent::RSN_TIMEOUT);
$this->_shutdown();
}
}

public function onTick()
{
$this->_tick();
}

public function onComplete()
{
$this->_shutdown();;
}

protected function _shutdown()
{
unregister_tick_function([$this, 'tick']);
}

public function __destruct()
{
$this->_shutdown();
}

}
31 changes: 31 additions & 0 deletions src/Events/ContextDoneEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
namespace Packaged\Context\Events;

use Packaged\Event\Events\AbstractEvent;

class ContextDoneEvent extends AbstractEvent
{
const RSN_DESTRUCT = 1;
const RSN_TRIGGER = 2;
const RSN_TIMEOUT = 3;

const TYPE = 'context.done';

private $_reason;

public function __construct($reason)
{
parent::__construct();
$this->_reason = $reason;
}

public function getType()
{
return static::TYPE;
}

public function reason()
{
return $this->_reason;
}
}
33 changes: 33 additions & 0 deletions src/Events/ContextTimeoutEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
namespace Packaged\Context\Events;

use Packaged\Event\Events\AbstractEvent;

class ContextTimeoutEvent extends AbstractEvent
{
const TYPE = 'context.timeout';
private $_expiryTime;
private $_duration;

public function __construct($duration, $expiryTime)
{
parent::__construct();
$this->_duration = $duration;
$this->_expiryTime = $expiryTime;
}

public function getType()
{
return static::TYPE;
}

public function getDuration()
{
return $this->_duration;
}

public function getExpiryTime()
{
return $this->_expiryTime;
}
}