From 9e2ba2d27bed4ccde52f5b4a715da2d791a8e3c1 Mon Sep 17 00:00:00 2001 From: Brooke Bryan Date: Wed, 12 Feb 2020 21:22:00 +0000 Subject: [PATCH] Context Done & Timeout --- src/Context.php | 49 ++++++++++++++++++++++++++++ src/ContextTimeout.php | 52 ++++++++++++++++++++++++++++++ src/Events/ContextDoneEvent.php | 31 ++++++++++++++++++ src/Events/ContextTimeoutEvent.php | 33 +++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 src/ContextTimeout.php create mode 100644 src/Events/ContextDoneEvent.php create mode 100644 src/Events/ContextTimeoutEvent.php diff --git a/src/Context.php b/src/Context.php index 913342f..eb1915b 100644 --- a/src/Context.php +++ b/src/Context.php @@ -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; @@ -25,6 +26,10 @@ 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; @@ -32,6 +37,7 @@ class Context implements ContextAware protected $_routeData; private $_id; + private $_done; private $_events; private $_request; private $_cookieJar; @@ -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) + { + } + } + } + } diff --git a/src/ContextTimeout.php b/src/ContextTimeout.php new file mode 100644 index 0000000..2ad49be --- /dev/null +++ b/src/ContextTimeout.php @@ -0,0 +1,52 @@ +_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(); + } + +} diff --git a/src/Events/ContextDoneEvent.php b/src/Events/ContextDoneEvent.php new file mode 100644 index 0000000..e19385c --- /dev/null +++ b/src/Events/ContextDoneEvent.php @@ -0,0 +1,31 @@ +_reason = $reason; + } + + public function getType() + { + return static::TYPE; + } + + public function reason() + { + return $this->_reason; + } +} diff --git a/src/Events/ContextTimeoutEvent.php b/src/Events/ContextTimeoutEvent.php new file mode 100644 index 0000000..f178f60 --- /dev/null +++ b/src/Events/ContextTimeoutEvent.php @@ -0,0 +1,33 @@ +_duration = $duration; + $this->_expiryTime = $expiryTime; + } + + public function getType() + { + return static::TYPE; + } + + public function getDuration() + { + return $this->_duration; + } + + public function getExpiryTime() + { + return $this->_expiryTime; + } +}