/** * Internal method to request multiple items. * * Options: * - ttl <float> * - The time-to-live * - namespace <string> * - The namespace to use * - select <array> * - An array of the information the returned item contains * - callback <callback> optional * - An result callback will be invoked for each item in the result set. * - The first argument will be the item array. * - The callback does not have to return anything. * * @param array $normalizedKeys * @param array $normalizedOptions * @return boolean * @throws Exception\ExceptionInterface * @see fetch() * @see fetchAll() */ protected function internalGetDelayed(array &$normalizedKeys, array &$normalizedOptions) { if ($this->stmtActive) { throw new Exception\RuntimeException('Statement already in use'); } if (isset($normalizedOptions['callback']) && !is_callable($normalizedOptions['callback'], false)) { throw new Exception\InvalidArgumentException('Invalid callback'); } $this->memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $normalizedOptions['namespace']); // redirect callback if (isset($normalizedOptions['callback'])) { $cb = function (MemcachedResource $memc, array &$item) use(&$normalizedOptions) { $select =& $normalizedOptions['select']; // handle selected key if (!in_array('key', $select)) { unset($item['key']); } // handle selected value if (!in_array('value', $select)) { unset($item['value']); } call_user_func($normalizedOptions['callback'], $item); }; if (!$this->memcached->getDelayed($normalizedKeys, false, $cb)) { throw $this->getExceptionByResultCode($this->memcached->getResultCode()); } } else { if (!$this->memcached->getDelayed($normalizedKeys)) { throw $this->getExceptionByResultCode($this->memcached->getResultCode()); } $this->stmtActive = true; $this->stmtOptions =& $normalizedOptions; } return true; }
/** * (non-PHPdoc) * @see \Cachearium\Backend\CacheRAM::prefetch() */ public function prefetch($data) { $keys = array(); foreach ($data as &$item) { $keys[] = $this->hashKey($item); } $this->memcached->getDelayed($keys); // TODO: fetchall vs get? }
/** * Get items that were marked to delay storage for purposes of removing blocking * * Options: * - namespace <string> optional * - The namespace to use (Default: namespace of object) * - select <array> optional * - An array of the information the returned item contains * (Default: array('key', 'value')) * - callback <callback> optional * - An result callback will be invoked for each item in the result set. * - The first argument will be the item array. * - The callback does not have to return anything. * * @param array $keys * @param array $options * @return bool * @throws Exception * * @triggers getDelayed.pre(PreEvent) * @triggers getDelayed.post(PostEvent) * @triggers getDelayed.exception(ExceptionEvent) */ public function getDelayed(array $keys, array $options = array()) { $baseOptions = $this->getOptions(); if ($this->stmtActive) { throw new Exception\RuntimeException('Statement already in use'); } elseif (!$baseOptions->getReadable()) { return false; } elseif (!$keys) { return true; } $this->normalizeOptions($options); if (isset($options['callback']) && !is_callable($options['callback'], false)) { throw new Exception\InvalidArgumentException('Invalid callback'); } if (!isset($options['select'])) { $options['select'] = array('key', 'value'); } $args = new ArrayObject(array('keys' => &$keys, 'options' => &$options)); try { $eventRs = $this->triggerPre(__FUNCTION__, $args); if ($eventRs->stopped()) { return $eventRs->last(); } $this->memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $options['namespace']); // redirect callback if (isset($options['callback'])) { $cb = function (MemcachedResource $memc, array &$item) use(&$options, $baseOptions) { $select =& $options['select']; // handle selected key if (!in_array('key', $select)) { unset($item['key']); } // handle selected value if (!in_array('value', $select)) { unset($item['value']); } call_user_func($options['callback'], $item); }; if (!$this->memcached->getDelayed($keys, false, $cb)) { throw $this->getExceptionByResultCode($this->memcached->getResultCode()); } } else { if (!$this->memcached->getDelayed($keys)) { throw $this->getExceptionByResultCode($this->memcached->getResultCode()); } $this->stmtActive = true; $this->stmtOptions =& $options; } $result = true; return $this->triggerPost(__FUNCTION__, $args, $result); } catch (\Exception $e) { return $this->triggerException(__FUNCTION__, $args, $e); } }
/** * Get items that were marked to delay storage for purposes of removing blocking * * @param array $keys * @param array $options * @return bool * @throws Exception * * @triggers getDelayed.pre(PreEvent) * @triggers getDelayed.post(PostEvent) * @triggers getDelayed.exception(ExceptionEvent) */ public function getDelayed(array $keys, array $options = array()) { $baseOptions = $this->getOptions(); if ($this->stmtActive) { throw new Exception\RuntimeException('Statement already in use'); } elseif (!$baseOptions->getReadable()) { return false; } elseif (!$keys) { return true; } $this->normalizeOptions($options); if (isset($options['callback']) && !is_callable($options['callback'], false)) { throw new Exception\InvalidArgumentException('Invalid callback'); } $args = new ArrayObject(array('key' => &$key, 'options' => &$options)); try { $eventRs = $this->triggerPre(__FUNCTION__, $args); if ($eventRs->stopped()) { return $eventRs->last(); } $prefix = $options['namespace'] . $baseOptions->getNamespaceSeparator(); $search = array(); foreach ($keys as $key) { $search[] = $prefix . $key; } $this->stmtIterator = $this->memcached->getDelayed($search); $this->stmtActive = true; $this->stmtOptions =& $options; if (isset($options['callback'])) { $callback = $options['callback']; while (($item = $this->fetch()) !== false) { call_user_func($callback, $item); } } $result = true; return $this->triggerPost(__FUNCTION__, $args, $result); } catch (\Exception $e) { return $this->triggerException(__FUNCTION__, $args, $e); } }
public function testGetDelayedSuccess() { $request = new MemcacheGetRequest(); $request->addKey("key"); $request->addKey("bar"); $request->setForCas(true); $response = new MemcacheGetResponse(); $item = $response->addItem(); $item->setKey("key"); $item->setValue("value"); $item->setFlags(0); // string. $item->setCasId(123456); $item = $response->addItem(); $item->setKey("bar"); $item->setValue("bar_value"); $item->setFlags(0); // string. $item->setCasId(2); $cb_count = 0; $cb = function ($val) use(&$cb_count) { $cb_count++; }; $this->apiProxyMock->expectCall('memcache', 'Get', $request, $response); $memcached = new Memcached(); $this->assertTrue($memcached->getDelayed(["key", "bar"], true, $cb)); $this->assertEquals($memcached->getResultCode(), Memcached::RES_SUCCESS); $result = $memcached->fetch(); $this->assertEquals($result["key"], "key"); $this->assertEquals($result["value"], "value"); $this->assertEquals($result["cas"], 123456); $result = $memcached->fetch(); $this->assertEquals($result["key"], "bar"); $this->assertEquals($result["value"], "bar_value"); $this->assertEquals($result["cas"], 2); $this->assertFalse($memcached->fetch()); $this->assertEquals($cb_count, 2); $this->apiProxyMock->verify(); }
/** * Request multiple keys without blocking. * * @link http://www.php.net/manual/en/memcached.getdelayed.php * * @param string|array $keys Array or string of key(s) to request. * @param string|array $groups Array or string of group(s) for the key(s). See buildKeys for more on how these are handled. * @param bool $with_cas Whether to request CAS token values also. * @param null $value_cb The result callback or NULL. * @return bool Returns TRUE on success or FALSE on failure. */ public function getDelayed($keys, $groups = 'default', $with_cas = false, $value_cb = NULL) { $derived_keys = $this->buildKeys($keys, $groups); return $this->m->getDelayed($derived_keys, $with_cas, $value_cb); }
<?php $m = new Memcached(); $m->addServer('127.0.0.1', 11211); $m->set('foo', 'bar'); $m->set('foo2', 'bar2'); $m->getDelayed(array('foo', 'foo2'), true); while ($result = $m->fetch()) { var_dump($result); }
<?php $m = new Memcached(); $m->addServer('localhost', 11211); $m->set('int', 99); $m->set('string', 'a simple string'); $m->set('array', array(11, 12)); $m->getDelayed(array('int', 'array'), true); while ($result = $m->fetch()) { var_dump($result); }
/** * @inheritdoc */ public function getDelayedByKeys($server_key, array $keys, $with_cas = false, callable $value_cb = null) { $keys = $this->prefixArrayOfKeys($keys); return parent::getDelayed($server_key, $keys, $with_cas, $value_cb); }