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; }
<?php require_once "../vendor/autoload.php"; use Hprose\Swoole\Server; use Hprose\Future; $server = new Server("http://0.0.0.0:1315"); $server->setErrorTypes(E_ALL); $server->setDebugEnabled(); $server->addFunction(function ($a, $b) use($server) { $promise = new Future(); swoole_timer_after(1000, function () use($a, $b, $promise) { $promise->resolve($a + $b); }); return $promise; }, "sum"); $server->start();
function settle($array) { return toFuture($array)->then(function ($array) { $keys = array_keys($array); $n = count($array); $result = array(); if ($n === 0) { return value($result); } $future = new Future(); $oncomplete = function ($index, $f) use($future, &$result, &$n, $keys) { return function () use($index, $f, $future, &$result, &$n, $keys) { $result[$index] = $f->inspect(); if (--$n === 0) { $array = array(); foreach ($keys as $key) { $array[$key] = $result[$key]; } $future->resolve($array); } }; }; foreach ($array as $index => $element) { $f = toFuture($element); $f->whenComplete($oncomplete($index, $f)); } return $future; }); }
public function publish($topic, array $options = array()) { $this->checkPushService(); if (is_array($topic)) { foreach ($topic as $t) { $this->publish($t, $options); } return $this; } $self = $this; $timeout = isset($options['timeout']) ? $options['timeout'] : $this->timeout; $heartbeat = isset($options['heartbeat']) ? $options['heartbeat'] : $this->heartbeat; $this->topics[$topic] = new ArrayObject(); return $this->addFunction(function ($id) use($self, $topic, $timeout, $heartbeat) { $topics = $self->getTopics($topic); if (isset($topics[$id])) { if ($topics[$id]->count < 0) { $topics[$id]->count = 0; } $messages = $topics[$id]->messages; if (!$messages->isEmpty()) { $message = $messages->shift(); $message->detector->resolve(true); $self->resetTimer($topics, $topic, $id); return $message->result; } else { $self->delTimer($topics, $id); $topics[$id]->count++; } } else { $topics[$id] = new stdClass(); $topics[$id]->messages = new SplQueue(); $topics[$id]->count = 1; $topics[$id]->heartbeat = $heartbeat; $this->timer->setImmediate(function () use($self, $topic, $id) { $onSubscribe = $self->onSubscribe; if (is_callable($onSubscribe)) { call_user_func($onSubscribe, $topic, $id, $self); } }); } if (isset($topics[$id]->request)) { $topics[$id]->request->resolve(null); } $request = new Future(); $request->complete(function () use($topics, $id) { $topics[$id]->count--; }); $topics[$id]->request = $request; return $self->setRequestTimer($topic, $id, $request, $timeout); }, $topic); }
<?php require_once "../vendor/autoload.php"; use Hprose\Future; $p1 = new Future(function () { return array(Future\value(1), Future\value(2)); }); $p1->then(function ($value) { var_dump($value); }); $p2 = Future\sync(function () { return array(Future\value(1), Future\value(2)); }); $p2->then(function ($value) { var_dump($value); });