function setRequestTimer($topic, $id, $request, $timeout) { if ($timeout > 0) { $self = $this; $topics = $this->getTopics($topic); $future = new Future(); $timer = $this->timer->setTimeout(function () use($future) { $future->reject(new TimeoutException('timeout')); }, $timeout); $request->whenComplete(function () use($self, $timer) { $self->timer->clearTimeout($timer); })->fill($future); return $future->catchError(function ($e) use($self, $topics, $topic, $id) { if ($e instanceof TimeoutException) { $checkoffline = function () use($self, &$checkoffline, $topics, $topic, $id) { $t = $topics[$id]; $t->timer = $self->timer->setTimeout($checkoffline, $t->heartbeat); if ($t->count < 0) { $self->offline($topics, $topic, $id); } else { --$t->count; } }; $checkoffline(); } }); } return $request; }
protected function sendAndReceive($request, stdClass $context) { $future = new Future(); $id = $this->getNextId(); $count =& $this->count; $futures =& $this->futures; $futures[$id] = $future; if ($context->timeout > 0) { $timeoutFuture = new Future(); $timer = swoole_timer_after($context->timeout, function () use($timeoutFuture) { $timeoutFuture->reject(new TimeoutException('timeout')); }); $future->whenComplete(function () use($timer) { swoole_timer_clear($timer); })->fill($timeoutFuture); $future = $timeoutFuture->catchError(function ($e) use(&$count, &$futures, $id) { unset($futures[$id]); --$count; throw $e; }, function ($e) { return $e instanceof TimeoutException; }); } if (!$this->connecting && ($this->ws === null || !$this->ws->isConnected())) { $this->connect(); } $ws = $this->ws; if ($count < 100) { ++$count; $this->ready->then(function () use($ws, $id, $request, &$futures) { $data = pack('N', $id) . $request; if ($ws->push($data, WEBSOCKET_OPCODE_BINARY, true) === false) { if (isset($futures[$id])) { $error = new Exception(socket_strerror($ws->errCode)); $futures[$id]->reject($error); } } }); } else { $this->requests[] = array($id, $request); } if ($context->oneway) { $future->resolve(null); } return $future; }
function any($array) { return toFuture($array)->then(function ($array) { $keys = array_keys($array); $n = count($array); if ($n === 0) { throw new RangeException('any(): $array must not be empty'); } $reasons = array(); $future = new Future(); $onfulfilled = array($future, "resolve"); $onrejected = function ($index) use($future, &$reasons, &$n, $keys) { return function ($reason) use($index, $future, &$reasons, &$n, $keys) { $reasons[$index] = $reason; if (--$n === 0) { $array = array(); foreach ($keys as $key) { $array[$key] = $reasons[$key]; } $future->reject($array); } }; }; foreach ($array as $index => $element) { $f = toFuture($element); $f->then($onfulfilled, $onrejected($index)); } return $future; }); }