您的位置:首页 > 数据库 > Memcache

memcache扩展0.2版本和0.4版本差异(一)

2013-01-16 13:20 316 查看
从方法列表里,可以发现,增加了两个对外开放的方法:pconnect和close

还是挨个看看每个方法做了哪些改进:

实际上connect和pconnect走的是同一个方法php_mmc_connect,参数不同,从参数persistent可以看出pconnect是建立持久化连接

在php_mmc_connect中,允许的参数个数改变了,0.2版本,主机和端口是必选参数,在0.4版本里,端口号成了可选参数

 if (ac < 1 || ac > 3 || zend_get_parameters_ex(ac, &host, &port, &timeout) == FAILURE) {

WRONG_PARAM_COUNT;

}

上面代码,1-3个参数都是合法的,定义默认端口的的宏在php_memcache.h中 #define MMC_DEFAULT_PORT 11211

接下来看看关于持久化连接的代码,如果用户通过pconnect建立连接,首先从客户端的哈希表中查找是否有现成的连接,没有则建立新的,如果有直接取出来使用。

if (persistent) {

list_entry *le;

mmc_debug("php_mmc_connect: seeking for persistent connection");

hash_key = emalloc(sizeof("mmc_connect___") - 1 + Z_STRLEN_PP(host) + MAX_LENGTH_OF_LONG + 1);

hash_key_len = sprintf(hash_key, "mmc_connect___%s:%d", Z_STRVAL_PP(host), real_port);

if (zend_hash_find(&EG(persistent_list), hash_key, hash_key_len+1, (void **) &le) == FAILURE) {

   注:查找哈希表,看是否有持久化连接

list_entry new_le;

mmc_debug("php_mmc_connect: connection wasn't found in the hash");

if ((mmc = mmc_open(Z_STRVAL_PP(host), Z_STRLEN_PP(host), real_port, timeout_sec, persistent TSRMLS_CC)) == NULL) {

mmc_debug("php_mmc_connect: connection failed");

efree(hash_key);

goto connect_done;

}

注:没有持久化连接,建立新的连接

mmc->id = zend_list_insert(mmc,le_pmemcache);

注:新建的连接注册到资源列表里,le_pmemcache是在MINIT里初始化的资源类型id

new_le.type = le_pmemcache;

new_le.ptr = mmc;

if (zend_hash_update(&EG(persistent_list), hash_key, hash_key_len+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {

efree(hash_key);

goto connect_done;

}

注:把新建的持久化连接放入哈希表

efree(hash_key);

MEMCACHE_G(num_persistent)++;

   注:更新持久连接数

}

else { 

   //到这说明在哈希表里找到了可用的持久化连接  

mmc_debug("php_mmc_connect: connection found in the hash");

if (le->type == le_pmemcache && le->ptr != NULL) {

if ((version = mmc_get_version(le->ptr TSRMLS_CC)) != NULL) {

mmc = (mmc_t *)le->ptr;

mmc_debug("memcache_connect: all right");

mmc->id = zend_list_insert(mmc,le_pmemcache);

     注:不明白为什么还要再注册一次连接资源,不是已经注册过了吗

/* Ok, server is alive and working */

efree(version);

efree(hash_key);

goto connect_done;

}

else {

//到这说明虽然有连接,但连接失效了,需要重新建立连接

list_entry new_le;

mmc_debug("php_mmc_connect: server has gone away, reconnecting..");

/* Daemon has gone away, reconnecting */

MEMCACHE_G(num_persistent)--;

if ((mmc = mmc_open(Z_STRVAL_PP(host), Z_STRLEN_PP(host), real_port, timeout_sec, persistent TSRMLS_CC)) == NULL) {

mmc_debug("php_mmc_connect: reconnect failed");

efree(hash_key);

zend_hash_del(&EG(persistent_list), hash_key, hash_key_len+1);

注:连接失败,从哈希表里删掉对应的连接

goto connect_done;

}

mmc->id = zend_list_insert(mmc,le_pmemcache);

注:连接成功,注册连接资源

new_le.type = le_pmemcache;

new_le.ptr = mmc;

if (zend_hash_update(&EG(persistent_list), hash_key, hash_key_len+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {

efree(hash_key);

goto connect_done;

}

注:更新哈希表

efree(hash_key);

MEMCACHE_G(num_persistent)++;

注:增加持久化连接数,有个不解的地方,既然用全局变量保存了持久化连接数,为什么不在最开始先判断连接数是否大于0,而是直接查询哈希表?

}

}

else {

    //重连

list_entry new_le;

mmc_debug("php_mmc_connect: smthing was wrong, reconnecting..");

if ((mmc = mmc_open(Z_STRVAL_PP(host), Z_STRLEN_PP(host), real_port, timeout_sec, persistent TSRMLS_CC)) == NULL) {

mmc_debug("php_mmc_connect: reconnect failed");

efree(hash_key);

zend_hash_del(&EG(persistent_list), hash_key, hash_key_len+1);

goto connect_done;

}

mmc->id = zend_list_insert(mmc,le_pmemcache);

new_le.type = le_pmemcache;

new_le.ptr = mmc;

if (zend_hash_update(&EG(persistent_list), hash_key, hash_key_len+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {

efree(hash_key);

goto connect_done;

}

efree(hash_key);

MEMCACHE_G(num_persistent)++;

}

}

}

注:上边的代码是关于查找和建立持久化连接的,大量代码冗余……

在所有连接失败的地方都有一行代码goto connect_done;

我们看看,连接失败后做了什么

connect_done:

if (mmc == NULL) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't connect to %s:%d",Z_STRVAL_PP(host), real_port);

RETURN_FALSE;

}

 注:连接建立失败

mmc->persistent = persistent;

if (mmc_object == NULL) {

object_init_ex(return_value, memcache_class_entry_ptr);

add_property_resource(return_value, "connection",mmc->id);

}

 注:非对象调用,因mmc_object=getThis();

else {

zval_dtor(mmc_object);

object_init_ex(mmc_object, memcache_class_entry_ptr);

add_property_resource(mmc_object, "connection",mmc->id);

RETURN_TRUE;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: