/** * Magic __call * Example: * $redis->lpush('mylist', microtime(true)); * @param string $name Command name * @param array $args Arguments * @return void */ public function __call($cmd, $args) { $cb = null; for ($i = sizeof($args) - 1; $i >= 0; --$i) { $a = $args[$i]; if ((is_array($a) || is_object($a)) && is_callable($a)) { $cb = CallbackWrapper::wrap($a); $args = array_slice($args, 0, $i); break; } elseif ($a !== null) { break; } } reset($args); $cmd = strtoupper($cmd); if ($this->sendSubCommand($cmd, $args, $cb)) { return; } if ($cmd === 'SENTINEL' || !isset($this->config->sentinelmaster->value)) { $this->sendCommand(null, $cmd, $args, $cb); return; } if ($this->currentMasterAddr !== null) { $this->sendCommand($this->currentMasterAddr, $cmd, $args, $cb); return; } $this->sentinel('get-master-addr-by-name', $this->config->sentinelmaster->value, function ($redis) use($cmd, $args, $cb) { $this->currentMasterAddr = 'tcp://' . $redis->result[0] . ':' . $redis->result[1]; $this->sendCommand($this->currentMasterAddr, $cmd, $args, $cb); }); }
public function status($phone, $id, $cb, $all = 0) { $cb = CallbackWrapper::wrap($cb); $this->appInstance->httpclient->get(['http://smsc.ru/sys/status.php', 'login' => $this->config->login->value, 'psw' => $this->config->password->value, 'phone' => $phone, 'id' => $id, 'fmt' => 3, 'all' => $all], function ($conn, $success) use($cb) { call_user_func($cb, json_decode($conn->body, true)); }); }
/** * @param $cb * @param $type * @param $args */ public function enqueue($cb, $type, $args, $add = [], $pushcb = null) { $ts = microtime(true); return $this->appInstance->jobqueue->push($type, $args, $ts, $add, function ($job) use($cb, $pushcb) { if ($cb !== NULL) { $this->callbacks[(string) MongoId::import($job->getId())] = CallbackWrapper::wrap($cb); } if ($pushcb !== null) { call_user_func($pushcb); } }); }
/** * Lookup a hash * @param $hash * @param $cb * @return $this */ public function lookup($hash, $cb) { $cb = CallbackWrapper::wrap($cb); $cj = new ComplexJob(function ($cj) use($cb) { $cb(array_merge(...$cj->results)); }); foreach ($this->indexes as $name => $index) { $cj($name, function ($name, $cj) use($hash, $index) { $index->lookup($hash, function ($res) use($cj, $name) { $cj[$name] = $res; }); }); } $cj(); return $this; }
/** * Constructor * @param Pool $pool Redis pool or connection * @param string $cmd Command * @param array $args Arguments * @param cllable $cbEnd Callback * @param integer $limit Limit */ public function __construct($pool, $cmd, $args = [], $cbEnd = null, $limit = false) { $this->conn = $pool; $this->cmd = $cmd; $this->args = empty($args) ? [] : $args; $this->limit = $limit; if (is_numeric($this->args[0])) { array_shift($this->args); } for ($i = sizeof($this->args) - 1; $i >= 0; --$i) { $a = $this->args[$i]; if ((is_array($a) || is_object($a)) && is_callable($a)) { $this->cb = CallbackWrapper::wrap($a); $this->args = array_slice($this->args, 0, $i); break; } elseif ($a !== null) { break; } } if ($cbEnd !== null) { $this->cbEnd = CallbackWrapper::wrap($cbEnd); } $this->doIteration(); }
/** * Commmit session data * @param callable $cb Callback * @return void */ public function sessionCommit($cb = null) { if (!$this->sessionFp || $this->sessionFlushing) { if ($cb) { call_user_func($cb, false); } return; } $this->sessionFlushing = true; $data = $this->sessionEncode(); $l = strlen($data); $cb = CallbackWrapper::wrap($cb); $this->sessionFp->write($data, function ($file, $result) use($l, $cb) { $file->truncate($l, function ($file, $result) use($cb) { $this->sessionFlushing = false; if ($cb) { call_user_func($cb, true); } }); }); }
/** * Push callback to the top of stack * @param callable $cb Callback * @return void */ public function unshift($cb) { parent::unshift(CallbackWrapper::wrap($cb)); }
/** * @TODO * @param string $name * @param array $args * @param callable $cb * @callback $cb ( ) * @return void */ public function command($name, $args, $cb = null) { if ($name === 'MULTI') { $this->acquire(); } elseif (substr($name, -9) === 'SUBSCRIBE') { if (!$this->subscribed) { $this->subscribed = true; $this->pool->servConnSub[$this->url] = $this; $this->acquire(); $this->setTimeouts(86400, 86400); // @TODO: remove timeout } $opcb = null; for ($i = sizeof($args) - 1; $i >= 0; --$i) { $a = $args[$i]; if ((is_array($a) || is_object($a)) && is_callable($a)) { $opcb = $cb; $cb = CallbackWrapper::wrap($a); $args = array_slice($args, 0, $i); break; } elseif ($a !== null) { break; } } } if ($name === 'SUBSCRIBE') { $this->subscribed(); $channels = []; foreach ($args as $arg) { if (!is_array($arg)) { $arg = [$arg]; } foreach ($arg as $chan) { $b = !isset($this->subscribeCb[$chan]); CallbackWrapper::addToArray($this->subscribeCb[$chan], $cb); if ($b) { $channels[] = $chan; } else { if ($opcb !== null) { call_user_func($opcb, $this); } } } } if (sizeof($channels)) { $this->sendCommand($name, $channels, $opcb); } } elseif ($name === 'PSUBSCRIBE') { $this->subscribed(); $channels = []; foreach ($args as $arg) { if (!is_array($arg)) { $arg = [$arg]; } foreach ($arg as $chan) { $b = !isset($this->psubscribeCb[$chan]); CallbackWrapper::addToArray($this->psubscribeCb[$chan], $cb); if ($b) { $channels[] = $chan; } else { if ($opcb !== null) { call_user_func($opcb, $this); } } } } if (sizeof($channels)) { $this->sendCommand($name, $channels, $opcb); } } elseif ($name === 'UNSUBSCRIBE') { $channels = []; foreach ($args as $arg) { if (!is_array($arg)) { $arg = [$arg]; } foreach ($arg as $chan) { if (!isset($this->subscribeCb[$chan])) { if ($opcb !== null) { call_user_func($opcb, $this); } return; } CallbackWrapper::removeFromArray($this->subscribeCb[$chan], $cb); if (sizeof($this->subscribeCb[$chan]) === 0) { $channels[] = $chan; unset($this->subscribeCb[$chan]); } else { if ($opcb !== null) { call_user_func($opcb, $this); } } } } if (sizeof($channels)) { $this->sendCommand($name, $channels, $opcb); } } elseif ($name === 'UNSUBSCRIBEREAL') { /* Race-condition-free UNSUBSCRIBE */ $old = $this->subscribeCb; $this->sendCommand('UNSUBSCRIBE', $args, function ($redis) use($cb, $args, $old) { if (!$redis) { call_user_func($cb, $redis); return; } foreach ($args as $arg) { if (!isset($this->subscribeCb[$arg])) { continue; } foreach ($old[$arg] as $oldcb) { CallbackWrapper::removeFromArray($this->subscribeCb[$arg], $oldcb); } if (!sizeof($this->subscribeCb[$arg])) { unset($this->subscribeCb[$arg]); } } if ($cb !== null) { call_user_func($cb, $this); } }); } elseif ($name === 'PUNSUBSCRIBE') { $channels = []; foreach ($args as $arg) { if (!is_array($arg)) { $arg = [$arg]; } foreach ($arg as $chan) { CallbackWrapper::removeFromArray($this->psubscribeCb[$chan], $cb); if (sizeof($this->psubscribeCb[$chan]) === 0) { $channels[] = $chan; unset($this->psubscribeCb[$chan]); } else { if ($opcb !== null) { call_user_func($opcb, $this); } } } } if (sizeof($channels)) { $this->sendCommand($name, $channels, $opcb); } } elseif ($name === 'PUNSUBSCRIBEREAL') { /* Race-condition-free PUNSUBSCRIBE */ $old = $this->psubscribeCb; $this->sendCommand('PUNSUBSCRIBE', $args, function ($redis) use($cb, $args, $old) { if (!$redis) { call_user_func($cb, $redis); return; } foreach ($args as $arg) { if (!isset($this->psubscribeCb[$arg])) { continue; } foreach ($old[$arg] as $oldcb) { CallbackWrapper::removeFromArray($this->psubscribeCb[$arg], $oldcb); } if (!sizeof($this->psubscribeCb[$arg])) { unset($this->psubscribeCb[$arg]); } } if ($cb !== null) { call_user_func($cb, $this); } }); } else { if ($name === 'MGET') { $this->resultTypeStack->push(static::RESULT_TYPE_ARGSVALS); $this->argsStack->push($args); } elseif ($name === 'HMGET') { $this->resultTypeStack->push(static::RESULT_TYPE_ARGSVALS); $a = $args; array_shift($a); $this->argsStack->push($a); } elseif ($name === 'HGETALL') { $this->resultTypeStack->push(static::RESULT_TYPE_ASSOC); } elseif (($name === 'ZRANGE' || $name === 'ZRANGEBYSCORE' || $name === 'ZREVRANGE' || $name === 'ZREVRANGEBYSCORE') && preg_grep('/WITHSCORES/i', $args)) { $this->resultTypeStack->push(static::RESULT_TYPE_ASSOC); } else { $this->resultTypeStack->push(static::RESULT_TYPE_DEFAULT); } $this->sendCommand($name, $args, $cb); if ($name === 'EXEC' || $name === 'DISCARD') { $this->release(); } } }
/** * Open file * @param string $path Path * @param string $flags Flags * @param callable $cb Callback (File) * @param integer $mode Mode (see EIO_S_I* constants) * @param integer $pri Priority * @return resource */ public static function open($path, $flags, $cb, $mode = null, $pri = EIO_PRI_DEFAULT) { $cb = CallbackWrapper::forceWrap($cb); if (!FileSystem::$supported) { $mode = File::convertFlags($flags, true); $fd = fopen($path, $mode); if (!$fd) { call_user_func($cb, false); return false; } $file = new File($fd, $path); call_user_func($cb, $file); return true; } $fdCacheKey = $path . "" . $flags; $noncache = strpos($flags, '!') !== false; $flags = File::convertFlags($flags); if (!$noncache && ($item = FileSystem::$fdCache->get($fdCacheKey))) { // cache hit $file = $item->getValue(); if ($file === null) { // operation in progress $item->addListener($cb); } else { // hit call_user_func($cb, $file); } return null; } elseif (!$noncache) { $item = FileSystem::$fdCache->put($fdCacheKey, null); $item->addListener($cb); } return eio_open($path, $flags, $mode, $pri, function ($path, $fd) use($cb, $flags, $fdCacheKey, $noncache) { if ($fd === -1) { if ($noncache) { call_user_func($cb, false); } else { FileSystem::$fdCache->put($fdCacheKey, false, self::$badFDttl); } return; } $file = new File($fd, $path); $file->append = ($flags | EIO_O_APPEND) === $flags; if ($file->append) { $file->stat(function ($file, $stat) use($cb, $noncache, $fdCacheKey) { $file->offset = $stat['size']; if (!$noncache) { $file->fdCacheKey = $fdCacheKey; FileSystem::$fdCache->put($fdCacheKey, $file); } else { call_user_func($cb, $file); } }); } else { if (!$noncache) { $file->fdCacheKey = $fdCacheKey; FileSystem::$fdCache->put($fdCacheKey, $file); } else { call_user_func($cb, $file); } } }, $path); }
/** * Move pointer to arbitrary position * @param integer $offset Offset * @param callable $cb Callback * @param integer $pri Priority * @return resource|false */ public function seek($offset, $cb, $pri = EIO_PRI_DEFAULT) { $cb = CallbackWrapper::forceWrap($cb); if (!\EIO::$supported) { fseek($this->fd, $offset); return false; } return eio_seek($this->fd, $offset, $pri, $cb, $this); }
/** * Sets callback which will be called once when got EOF * @param callable $cb * @return this */ public function onEOF($cb = NULL) { $this->onEOF = CallbackWrapper::wrap($cb); return $this; }
/** * Aggregate function * @param array $p Hash of properties (offset, limit, opts, key, col) * @param callable $cb Callback called when response received * @callback $cb ( ) * @return void */ public function aggregate($p, $cb) { $this->_params($p); $e = explode('.', $p['col'], 2); $query = ['aggregate' => $e[1]]; if (isset($p['rp'])) { $query['$readPreference'] = $p['rp']; unset($p['rp']); } foreach ($p as $k => $v) { if (substr($k, 0, 1) === '$' || $k === 'pipeline') { $query[$k] = $v; } } $cb = CallbackWrapper::wrap($cb); try { $this->request(self::OP_QUERY, pack('V', $p['opts']) . $e[0] . '.$cmd' . "" . pack('VV', $p['offset'], $p['limit']) . bson_encode($query) . (isset($p['fields']) ? bson_encode($p['fields']) : ''), true, null, function ($conn, $reqId = null) use($p, $cb) { if (!$conn) { !$cb || $cb(['$err' => 'Connection error.']); return; } $conn->requests[$reqId] = [$p['col'], $cb, false]; }); } catch (\MongoException $e) { Daemon::log('MongoClient exception: ' . $e->getMessage() . ': ' . $e->getTraceAsString()); if ($cb !== null) { $cb(['$err' => $e->getMessage(), '$query' => $query, '$fields' => isset($p['fields']) ? $p['fields'] : null]); } } }
/** * Adds listener * @param callable $cb Callback * @return void */ public function addListener($cb) { if ($this->state === self::STATE_DONE) { call_user_func($cb, $this); return; } $this->listeners[] = CallbackWrapper::wrap($cb); }
public function setCallback($cb) { $this->callback = CallbackWrapper::wrap($cb); }
/** * Sends arbitrary command * @param string $packet A packet for sending by the connected client to Asterisk * @param callable $cb Callback called when response received * @param array $assertion If more events may follow as response this is a main part or full an action complete event indicating that all data has been sent */ protected function command($packet, $cb, $assertion = null) { if ($this->finished) { throw new ConnectionFinished(); } if ($this->state !== self::CONN_STATE_HANDSHAKED_OK) { return; } $actionId = Daemon::uniqid(); if (!is_callable($cb, true)) { $cb = false; } $this->callbacks[$actionId] = CallbackWrapper::wrap($cb); if ($assertion !== null) { $this->assertions[$actionId] = $assertion; } $this->write($packet); $this->write('ActionID: ' . $actionId . "\r\n\r\n"); }
/** * Unbind event(s) or callback from event(s) * @param string|array $event Event name * @param callable $cb Callback, optional * @return this */ public function unbind($event, $cb = null) { if ($cb !== null) { $cb = CallbackWrapper::wrap($cb); } is_array($event) or $event = [$event]; $success = true; foreach ($event as $e) { if (!isset($this->eventHandlers[$e])) { $success = false; continue; } if ($cb === null) { unset($this->eventHandlers[$e]); continue; } CallbackWrapper::removeFromArray($this->eventHandlers[$e], $cb); } return $this; }
/** * Enqueue callback * @param callable $cb Callback * @param integer $pri Priority * @return void */ public function enqueue($cb, $pri = 0) { parent::insert(CallbackWrapper::wrap($cb), $pri); }
/** * Returns string of pseudo random bytes * @param integer $len Length of desired string * @param callable $cb Callback * @param integer $pri Priority of EIO operation * @param boolean $hang If true, we shall use /dev/random instead of /dev/urandom and it may cause a delay * @return integer */ public static function randomBytes($len, $cb, $pri = 0, $hang = false) { $cb = CallbackWrapper::wrap($cb); FileSystem::open('/dev/' . ($hang ? '' : 'u') . 'random', 'r', function ($file) use($len, $cb, $pri) { if (!$file) { $cb(false); return; } $file->read($len, 0, function ($file, $data) use($cb) { $cb($data); }, $pri); }, null, $pri); }
/** * Adds listener * @param callable $cb */ public function addListener($cb) { $this->listeners[] = CallbackWrapper::wrap($cb); }
/** * Lookup a hash * @param $hash * @param $cb * @return $this */ public function lookup($hash, $cb) { $cb = CallbackWrapper::wrap($cb); if (!$this->count()) { $this->queue->push(function () use($hash, $cb) { $this->lookup($hash, $cb); }); return; } if (!$this->valid()) { $this->rewind(); } $process = $this->current(); $process->lookup($hash, $cb); $this->next(); return $this; }