Skip to content

Commit

Permalink
Allow getMulti to return partial results.
Browse files Browse the repository at this point in the history
  • Loading branch information
Teddy Grenman committed Dec 4, 2009
1 parent 542b623 commit 640927e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 12 deletions.
43 changes: 33 additions & 10 deletions php_memcached.c
Expand Up @@ -626,6 +626,8 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
}

status = memcached_mget_by_key(m_obj->memc, server_key, server_key_len, mkeys, mkeys_len, i);
// Handle error, but ignore, there might still be some result
php_memc_handle_error(i_obj, status TSRMLS_CC);

/*
* Restore the CAS support flag, but only if we had to turn it on.
Expand All @@ -638,10 +640,6 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke

efree(mkeys);
efree(mkeys_len);
if (php_memc_handle_error(i_obj, status TSRMLS_CC) < 0) {
zval_dtor(return_value);
RETURN_FALSE;
}

/*
* Iterate through the result set and create the result array. The CAS tokens are
Expand All @@ -652,9 +650,13 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
array_init(cas_tokens);
}

status = MEMCACHED_SUCCESS;
memcached_result_create(m_obj->memc, &result);
while ((memcached_fetch_result(m_obj->memc, &result, &status)) != NULL) {
if (status != MEMCACHED_SUCCESS) {
status = MEMCACHED_SOME_ERRORS;
php_memc_handle_error(i_obj, status TSRMLS_CC);
continue;
}

payload = memcached_result_value(&result);
payload_len = memcached_result_length(&result);
Expand All @@ -665,12 +667,21 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
MAKE_STD_ZVAL(value);

if (php_memc_zval_from_payload(value, payload, payload_len, flags, m_obj->serializer TSRMLS_CC) < 0) {
// XXX: remember memcached_quit?
zval_ptr_dtor(&value);
zval_dtor(return_value);
i_obj->rescode = MEMC_RES_PAYLOAD_FAILURE;
memcached_result_free(&result);
RETURN_FALSE;
if (EG(exception)) {
status = MEMC_RES_PAYLOAD_FAILURE;
php_memc_handle_error(i_obj, status TSRMLS_CC);

break;
}
status = MEMCACHED_SOME_ERRORS;
i_obj->rescode = MEMCACHED_SOME_ERRORS;

continue;
}

i++;
add_assoc_zval_ex(return_value, res_key, res_key_len+1, value);
if (cas_tokens) {
cas = memcached_result_cas(&result);
Expand All @@ -680,7 +691,12 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke

memcached_result_free(&result);

if (status != MEMCACHED_END && php_memc_handle_error(i_obj, status TSRMLS_CC) < 0) {
if (EG(exception)) {
// XXX: cas_tokens should only be set on success, currently we're destructive
if (cas_tokens) {
zval_dtor(cas_tokens);
ZVAL_NULL(cas_tokens);
}
zval_dtor(return_value);
RETURN_FALSE;
}
Expand Down Expand Up @@ -2222,6 +2238,13 @@ static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRM
result = 0;
break;

case MEMCACHED_SOME_ERRORS:
i_obj->rescode = status;
/* Hnngghgh! */
i_obj->memc_errno = i_obj->obj->memc->cached_errno;
result = 0;
break;

default:
i_obj->rescode = status;
/* Hnngghgh! */
Expand Down
6 changes: 4 additions & 2 deletions tests/experimental/getmulti_badserver.phpt
Expand Up @@ -14,7 +14,9 @@ var_dump($m->getMulti(array('foo', 'bar')));
echo $m->getResultMessage(), "\n";

--EXPECT--
bool(false)
array(0) {
}
NO SERVERS DEFINED
bool(false)
array(0) {
}
SYSTEM ERROR
28 changes: 28 additions & 0 deletions tests/experimental/getmulti_partial_error.phpt
@@ -0,0 +1,28 @@
--TEST--
Memcached::getMulti() partial error
--SKIPIF--
<?php if (!extension_loaded("memcached")) print "skip"; ?>
--FILE--
<?php
$m = new Memcached();
$m->addServer('localhost', 11211, 1);

$data = array();
for ($i = 0; $i < 1000; $i++) {
$data['key' . $i] = 'value' . $i;
}
var_dump($m->setMulti($data));

var_dump($m->addServer('localhost', 37712, 1));

$v = $m->getMulti(array_keys($data));
var_dump(is_array($v));
var_dump(count($v) < count($data));
var_dump($m->getResultCode() == Memcached::RES_SUCCESS);

--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)

0 comments on commit 640927e

Please sign in to comment.