设为首页 加入收藏

TOP

Python Redis链接建立实现分析(二)
2015-02-02 14:43:11 来源: 作者: 【 】 浏览:39
Tags:Python Redis 链接 建立 实现 分析


? ? ? ? "Get a connection from the pool"


? ? ? ? self._checkpid()


? ? ? ? try:


? ? ? ? ? ? connection = self._available_connections.pop()? #获取并删除代表连接的元素,在第一次获取connectiong时,因为_available_connections是一个空的数组,


? ? ? ? ? ? 会直接调用make_connection方法


? ? ? ? except IndexError:


? ? ? ? ? ? connection = self.make_connection()


? ? ? ? self._in_use_connections.add(connection)? #向代表正在使用的连接的集合中添加元素


? ? ? ? return connection?


? ? def make_connection(self): #在_available_connections数组为空时获取连接调用的方法


? ? ? ? "Create a new connection"


? ? ? ? if self._created_connections >= self.max_connections:? #判断创建的连接是否已经达到最大限制,max_connections可以通过参数初始化


? ? ? ? ? ? raise ConnectionError("Too many connections")


? ? ? ? self._created_connections += 1? #把代表已经创建的连接的数值+1


? ? ? ? return self.connection_class(**self.connection_kwargs)? ? #返回有效的连接,默认为Connection(**self.connection_kwargs)


? ? def release(self, connection):? #释放连接,链接并没有断开,只是存在链接池中


? ? ? ? "Releases the connection back to the pool"


? ? ? ? self._checkpid()


? ? ? ? if connection.pid != self.pid:


? ? ? ? ? ? return


? ? ? ? self._in_use_connections.remove(connection)? #从集合中删除元素


? ? ? ? self._available_connections.append(connection) #并添加到_available_connections 的数组中


? ? def disconnect(self): #断开所有连接池中的链接


? ? ? ? "Disconnects all connections in the pool"


? ? ? ? all_conns = chain(self._available_connections,


? ? ? ? ? ? ? ? ? ? ? ? ? self._in_use_connections)


? ? ? ? for connection in all_conns:


? ? ? ? ? ? connection.disconnect()


execute_command最终调用的是Connection.send_command方法,关闭链接为 Connection.disconnect方法,而Connection类的实现:


class Connection(object):


? ? "Manages TCP communication to and from a Redis server"


? ? def __del__(self):? #对象删除时的操作,调用disconnect释放连接


? ? ? ? try:


? ? ? ? ? ? self.disconnect()


? ? ? ? except Exception:


? ? ? ? ? ? pass



核心的链接建立方法是通过socket模块实现:


? def _connect(self):


? ? ? ? err = None


? ? ? ? for res in socket.getaddrinfo(self.host, self.port, 0,


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? socket.SOCK_STREAM):


? ? ? ? ? ? family, socktype, proto, canonname, socket_address = res


? ? ? ? ? ? sock = None


? ? ? ? ? ? try:


? ? ? ? ? ? ? ? sock = socket.socket(family, socktype, proto)


? ? ? ? ? ? ? ? # TCP_NODELAY


? ? ? ? ? ? ? ? sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)


? ? ? ? ? ? ? ? # TCP_KEEPALIVE


? ? ? ? ? ? ? ? if self.socket_keepalive:? #构造函数中默认 socket_keepalive=False,因此这里默认为短连接


? ? ? ? ? ? ? ? ? ? sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)


? ? ? ? ? ? ? ? ? ? for k, v in iteritems(self.socket_keepalive_options):


? ? ? ? ? ? ? ? ? ? ? ? sock.setsockopt(socket.SOL_TCP, k, v)


? ? ? ? ? ? ? ? # set the socket_connect_timeout before we connect


? ? ? ? ? ? ? ? sock.settimeout(self.socket_connect_timeout)? #构造函数中默认socket_connect_timeout=None,即连接为blocking的模式


? ? ? ? ? ? ? ? # connect


? ? ? ? ? ? ? ? sock.connect(socket_address)


? ? ? ? ? ? ? ? # set the socket_timeout now that we're connected


? ? ? ? ? ? ? ? sock.settimeout(self.socket_timeout)? #构造函数中默认socket_timeout=None


? ? ? ? ? ? ? ? return sock


? ? ? ? ? ? except socket.error as _:


? ? ? ? ? ? ? ? err = _


? ? ? ? ? ? ? ? if sock is not None:


? ? ? ? ? ? ? ? ? ? sock.close()


.....


关闭链接的方法:


? ? def disconnect(self):


? ? ? ? "Disconnects from the Redis server"


? ? ? ? self._parser.on_disconnect()


? ? ? ? if self._sock is None:


? ? ? ? ? ? return


? ? ? ? try:


? ? ? ? ? ? self._sock.shutdown(socket.SHUT_RDWR)? #先shutdown再close


? ? ? ? ? ? self._sock.close()


? ? ? ? except socket.error:


? ? ? ? ? ? pass


? ? ? ? self._sock = None


? ? ?
可以小结如下
1)默认情况下每创建一个Redis实例都会构造出一个ConnectionPool实例,每一次访问redis都会从这个连接池得到一个连接,操作完成后会把该连接放回连接池(连接并没有释放),可以构造一个统一的ConnectionPool,在创建Red

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Python使用xinetd处理多客户端 下一篇Java中ListIterator和Iterator详..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: