1<?php 2 3namespace React\Promise; 4 5class CancellationQueue 6{ 7 private $started = false; 8 private $queue = []; 9 10 public function __invoke() 11 { 12 if ($this->started) { 13 return; 14 } 15 16 $this->started = true; 17 $this->drain(); 18 } 19 20 public function enqueue($cancellable) 21 { 22 if (!\is_object($cancellable) || !\method_exists($cancellable, 'then') || !\method_exists($cancellable, 'cancel')) { 23 return; 24 } 25 26 $length = \array_push($this->queue, $cancellable); 27 28 if ($this->started && 1 === $length) { 29 $this->drain(); 30 } 31 } 32 33 private function drain() 34 { 35 for ($i = key($this->queue); isset($this->queue[$i]); $i++) { 36 $cancellable = $this->queue[$i]; 37 38 $exception = null; 39 40 try { 41 $cancellable->cancel(); 42 } catch (\Throwable $exception) { 43 } catch (\Exception $exception) { 44 } 45 46 unset($this->queue[$i]); 47 48 if ($exception) { 49 throw $exception; 50 } 51 } 52 53 $this->queue = []; 54 } 55} 56