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;
}
还是挨个看看每个方法做了哪些改进:
实际上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;
}
相关文章推荐
- memcache扩展0.2版本和0.4版本差异(二)
- memcache扩展(0.2版本)源代码讲解(memcache_delete)
- memcache扩展(0.2版本)源代码讲解(memcache_get_version)
- memcache扩展(0.2版本)源代码讲解(memcache_set)
- memcache扩展(0.2版本)源代码讲解(memcache_increment)
- memcache扩展(0.2版本)源代码讲解(memcache_get)
- memcache扩展(0.2版本)源代码讲解(memcache_connect)
- 安装php7及安装memcache扩展出现的新旧php版本兼容扩展的问题
- windows phpinfo上不能找到memcache扩展 php版本5.6
- windows下安装php5.2.*,php5.3.*,php5.4.*版本的memcache扩展(转)
- 一个好用的字符过滤,差异匹配补丁的扩展库,各语言版本
- windows下安装php5.2.*,php5.3.*,php5.4.*版本的memcache扩展
- windows下安装php5.2.*,php5.3.*,php5.4.*版本的memcache扩展
- Oracle数据库版本10.2实际进入扩展支持Extended Support周期
- php扩展模块eAccelerator,mysql_pdo,memcache安装配置
- 利用eclipse比较两个文件的代码差异或者一个文件不同版本之间的异同
- POI 读取 Excel 文件(2003版本与2007版本的差异之处)
- mac mamp php redis 扩展安装 亲测可用 版本php7
- iOS 6版本与之前版本差异总结
- 通达OA 2013版和2013增强版两个版本开发的一些差异