Overview

Namespaces

  • Alchemy
    • core
      • query
      • schema
    • dialect
    • engine
    • orm
    • tests
    • util
      • promise
  • PHP

Classes

  • Promise
  • Signal
  • SignalFn_Then
  • Waitable

Interfaces

  • IPromisable

Exceptions

  • SerializableException
  • TimeoutException
  • TypeException
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace Alchemy\util\promise;
  4: 
  5: 
  6: /**
  7:  * Abstraction for objects which can be checked (non-blocking) or waited upon
  8:  * to resolve (blocking, with optional timeout).
  9:  */
 10: class Waitable {
 11:     private $resultType = null;
 12:     protected $result = null;
 13: 
 14:     protected $started = null;
 15:     protected $timeout = null;
 16:     protected $spin = 10;
 17: 
 18: 
 19:     public function __construct($type = null) {
 20:         $this->resultType = $type;
 21:     }
 22: 
 23: 
 24:     /**
 25:      * Immediately return the value of the Waitable, resolved or not
 26:      *
 27:      * @return  mixed current value
 28:      */
 29:     public function __invoke() {
 30:         $this->check();
 31:         return $this->result;
 32:     }
 33: 
 34: 
 35:     /**
 36:      * Returns whether or not the Waitable is resolved.
 37:      *
 38:      * @return  boolean resolved or not
 39:      */
 40:     public function check() {
 41:         $this->precheck();
 42: 
 43:         return $this->result !== null;
 44:     }
 45: 
 46: 
 47:     /**
 48:      * Subclasses override this to do something during check()
 49:      */
 50:     protected function precheck() {}
 51: 
 52: 
 53:     /**
 54:      * Resolve the Waitable to a value, Exception, or NULL to leave it unresolved.
 55:      *
 56:      * @param  mixed $result
 57:      * @return this
 58:      */
 59:     public function resolve($result) {
 60:         if ($result === null
 61:             || $result instanceof \Exception
 62:             || $result instanceof Waitable) {
 63:             $this->result = $result;
 64:         } elseif ($this->resultType && !($result instanceof $this->resultType)) {
 65:             $type = is_object($result) ? get_class($result) : gettype($result);
 66:             $this->result = new TypeException("Expected {$this->resultType}, got {$type}");
 67:         } else {
 68:             $this->result = $result;
 69:         }
 70: 
 71:         return $this;
 72:     }
 73: 
 74: 
 75:     /**
 76:      * Sets the timeout for this Waitable.
 77:      * $obj->timeout() will cause the Waitable to not wait at all.
 78:      *
 79:      * @param  integer $ms     in milliseconds. 0 = immediately, null = never
 80:      * @param  integer $spin   delay between spinlock checks
 81:      * @param  boolean $reset  whether or not to reset the timer
 82:      */
 83:     public function timeout($ms = 0, $spin = 10, $reset = false) {
 84:         if ($reset || $this->started === null) {
 85:             $this->started = microtime(true);
 86:         }
 87: 
 88:         $this->timeout = ($ms === null) ? null : $this->started + $ms;
 89:         $this->spin = $spin;
 90: 
 91:         return $this;
 92:     }
 93: 
 94: 
 95:     /**
 96:      * Get the expected result type, if any, of this Waitable.
 97:      *
 98:      * @return string|null
 99:      */
100:     public function type() {
101:         return $this->resultType;
102:     }
103: 
104: 
105:     /**
106:      * Blocks until either the Waitable resolves or times out.
107:      *
108:      * @return $result resolved value or an Exception
109:      */
110:     public function wait() {
111:         while(!$this->check() && ($this->timeout && (microtime(true) < $this->timeout))) {
112:             usleep($this->spin * 1000);
113:         }
114: 
115:         if ($this->result === null) {
116:             $this->result = new TimeoutException();
117:         }
118: 
119:         return $this->result;
120:     }
121: 
122: 
123:     /**
124:      * Same as wait(), except it throws Exceptions instead of returning them.
125:      *
126:      * @return $result resolved value
127:      */
128:     public function expect() {
129:         if ($this->result === null) {
130:             $this->wait();
131:         }
132: 
133:         if ($this->result instanceof \Exception) {
134:             throw $this->result;
135:         }
136: 
137:         return $this->result;
138:     }
139: }
140: 
141: class SerializableException extends \Exception {
142:     public function __sleep() {
143:         return array('message', 'code', 'file', 'line');
144:     }
145: }
146: 
147: class TypeException extends SerializableException {}
148: class TimeoutException extends SerializableException {}
API documentation generated by ApiGen 2.8.0