namedtuple
Python的namedtuple使用详解_kongxx的专栏-CSDN博客_namedtuple https://blog.csdn.net/kongxx/article/details/51553362
redlock-py/__init__.py at master · SPSCommerce/redlock-py https://github.com/SPSCommerce/redlock-py/blob/master/redlock/__init__.py
| Lock = namedtuple("Lock", ("validity", "resource", "key")) |
import logging
import string
import random
import time
from collections import namedtuple
import redis
from redis.exceptions import RedisError
# Python 3 compatibility
string_type = getattr(__builtins__, 'basestring', str)
try:
basestring
except NameError:
basestring = str
Lock = namedtuple("Lock", ("validity", "resource", "key"))
class CannotObtainLock(Exception):
pass
class MultipleRedlockException(Exception):
def __init__(self, errors, *args, **kwargs):
super(MultipleRedlockException, self).__init__(*args, **kwargs)
self.errors = errors
def __str__(self):
return ' :: '.join([str(e) for e in self.errors])
def __repr__(self):
return self.__str__()
class Redlock(object):
default_retry_count = 3
default_retry_delay = 0.2
clock_drift_factor = 0.01
unlock_script = """
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end"""
def __init__(self, connection_list, retry_count=None, retry_delay=None):
self.servers = []
for connection_info in connection_list:
try:
if isinstance(connection_info, string_type):
server = redis.StrictRedis.from_url(connection_info)
elif type(connection_info) == dict:
server = redis.StrictRedis(**connection_info)
else:
server = connection_info
self.servers.append(server)
except Exception as e:
raise Warning(str(e))
self.quorum = (len(connection_list) // 2) + 1
if len(self.servers) < self.quorum:
raise CannotObtainLock(
"Failed to connect to the majority of redis servers")
self.retry_count = retry_count or self.default_retry_count
self.retry_delay = retry_delay or self.default_retry_delay
def lock_instance(self, server, resource, val, ttl):
try:
assert isinstance(ttl, int), 'ttl {} is not an integer'.format(ttl)
except AssertionError as e:
raise ValueError(str(e))
return server.set(resource, val, nx=True, px=ttl)
def unlock_instance(self, server, resource, val):
try:
server.eval(self.unlock_script, 1, resource, val)
except Exception as e:
logging.exception("Error unlocking resource %s in server %s", resource, str(server))
def get_unique_id(self):
CHARACTERS = string.ascii_letters + string.digits
return ''.join(random.choice(CHARACTERS) for _ in range(22)).encode()
def lock(self, resource, ttl):
retry = 0
val = self.get_unique_id()
# Add 2 milliseconds to the drift to account for Redis expires
# precision, which is 1 millisecond, plus 1 millisecond min
# drift for small TTLs.
drift = int(ttl * self.clock_drift_factor) + 2
redis_errors = list()
while retry < self.retry_count:
n = 0
start_time = int(time.time() * 1000)
del redis_errors[:]
for server in self.servers:
try:
if self.lock_instance(server, resource, val, ttl):
n += 1
except RedisError as e:
redis_errors.append(e)
elapsed_time = int(time.time() * 1000) - start_time
validity = int(ttl - elapsed_time - drift)
if validity > 0 and n >= self.quorum:
if redis_errors:
raise MultipleRedlockException(redis_errors)
return Lock(validity, resource, val)
else:
for server in self.servers:
try:
self.unlock_instance(server, resource, val)
except:
pass
retry += 1
time.sleep(self.retry_delay)
return False
def unlock(self, lock):
redis_errors = []
for server in self.servers:
try:
self.unlock_instance(server, lock.resource, lock.key)
except RedisError as e:
redis_errors.append(e)
if redis_errors:
raise MultipleRedlockException(redis_errors)
import loggingimport stringimport randomimport timefrom collections import namedtuple
import redisfrom redis.exceptions import RedisError
# Python 3 compatibilitystring_type = getattr(__builtins__, 'basestring', str)
try: basestringexcept NameError: basestring = str
Lock = namedtuple("Lock", ("validity", "resource", "key"))
class CannotObtainLock(Exception): pass
class MultipleRedlockException(Exception): def __init__(self, errors, *args, **kwargs): super(MultipleRedlockException, self).__init__(*args, **kwargs) self.errors = errors
def __str__(self): return ' :: '.join([str(e) for e in self.errors])
def __repr__(self): return self.__str__()
class Redlock(object):
default_retry_count = 3 default_retry_delay = 0.2 clock_drift_factor = 0.01 unlock_script = """ if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end"""
def __init__(self, connection_list, retry_count=None, retry_delay=None): self.servers = [] for connection_info in connection_list: try: if isinstance(connection_info, string_type): server = redis.StrictRedis.from_url(connection_info) elif type(connection_info) == dict: server = redis.StrictRedis(**connection_info) else: server = connection_info self.servers.append(server) except Exception as e: raise Warning(str(e)) self.quorum = (len(connection_list) // 2) + 1
if len(self.servers) < self.quorum: raise CannotObtainLock( "Failed to connect to the majority of redis servers") self.retry_count = retry_count or self.default_retry_count self.retry_delay = retry_delay or self.default_retry_delay
def lock_instance(self, server, resource, val, ttl): try: assert isinstance(ttl, int), 'ttl {} is not an integer'.format(ttl) except AssertionError as e: raise ValueError(str(e)) return server.set(resource, val, nx=True, px=ttl)
def unlock_instance(self, server, resource, val): try: server.eval(self.unlock_script, 1, resource, val) except Exception as e: logging.exception("Error unlocking resource %s in server %s", resource, str(server))
def get_unique_id(self): CHARACTERS = string.ascii_letters + string.digits return ''.join(random.choice(CHARACTERS) for _ in range(22)).encode()
def lock(self, resource, ttl): retry = 0 val = self.get_unique_id()
# Add 2 milliseconds to the drift to account for Redis expires # precision, which is 1 millisecond, plus 1 millisecond min # drift for small TTLs. drift = int(ttl * self.clock_drift_factor) + 2
redis_errors = list() while retry < self.retry_count: n = 0 start_time = int(time.time() * 1000) del redis_errors[:] for server in self.servers: try: if self.lock_instance(server, resource, val, ttl): n += 1 except RedisError as e: redis_errors.append(e) elapsed_time = int(time.time() * 1000) - start_time validity = int(ttl - elapsed_time - drift) if validity > 0 and n >= self.quorum: if redis_errors: raise MultipleRedlockException(redis_errors) return Lock(validity, resource, val) else: for server in self.servers: try: self.unlock_instance(server, resource, val) except: pass retry += 1 time.sleep(self.retry_delay) return False
def unlock(self, lock): redis_errors = [] for server in self.servers: try: self.unlock_instance(server, lock.resource, lock.key) except RedisError as e: redis_errors.append(e) if redis_errors: raise MultipleRedlockException(redis_errors)
namedtuple的更多相关文章
- collections 模块(namedtuple, deque, Counter )
基本介绍 我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型 ...
- Python_Day_05 计数器(counter),有序字典(OrderDict),默认字典(defaultdict),可命名元祖(namedtuple),双向队列(deque),单项队列(deuqe.Queue)
Counter(计数器) 是一个字典的子类,存储形式同样为字典,其中存储的键为字典的元素,值为元素出现的次数,在使用之前我们需要先导入文件 import collections 初始化一个计数器 im ...
- 计数器(counter),有序字典(OrderDict),默认字典(defaultdict),可命名元祖(namedtuple),双向队列(deque),单项队列(deuqe.Queue)
Python_Day_05 计数器(counter),有序字典(OrderDict),默认字典(defaultdict),可命名元祖(namedtuple),双向队列(deque),单项队列(deuq ...
- 再谈collections模块defaultdict()和namedtuple()
defaultdict()和namedtuple()是collections模块里面2个很实用的扩展类型.一个继承自dict系统内置类型,一个继承自tuple系统内置类型.在扩展的同时都添加了额外的很 ...
- Python namedtuple
我们都知道Python中的tuple是一个非常高效的集合对象,但是我们只能通过索引的方式访问这个集合中的元素,比如下面的代码: Bob=('bob',30,'male') print'Represen ...
- Python元类实践--自己定义一个和collections中一样的namedtuple
大家可能很熟悉在collections模块中有一个很好用的扩展数据类型-namedtuple. 如果你还不知道这个类型,那么请翻看标准手册. 我利用元类轻松定义一个namedtuple. 先把代码贴上 ...
- python:学习defaultdict,namedtuple
# -*- coding: utf-8 -*-__author__ = 'Administrator'import bisect#排序说明:http://en.wikipedia.org/wiki/i ...
- collection系列用法-namedtuple()
namedtuple() 参考文章地址:http://www.cnblogs.com/herbert/p/3468294.html namedtuple是继承自tuple的子类.namedtuple和 ...
- python-Day3-set 集合-counter计数器-默认字典(defaultdict) -可命名元组(namedtuple)-有序字典(orderedDict)-双向队列(deque)--Queue单项队列--深浅拷贝---函数参数
上节内容回顾:C语言为什么比起他语言块,因为C 会把代码变异成机器码Pyhton 的 .pyc文件是什么python 把.py文件编译成的.pyc文件是Python的字节码, 字符串本质是 字符数组, ...
- python中的collections.namedtuple
简介 collections.namedtuple是一个工厂方法,它可以动态的创建一个继承tuple的子类.跟tuple相比,返回的子类可以使用名称来访问元素. 使用方法 用一个例子来介绍: > ...
随机推荐
- 你好,Spring!
交个朋友 拿人钱财替人干活儿,在不影响工作的前提下,想做到很高频率的更新很难,但是我也尽力输出,不能为了写而写,宁缺毋滥吧. 我的想法是这样的,接下来的一段时间专门写Spring框架.整体思路就是:入 ...
- 为什么游戏公司的server不愿意微服务化?
背景介绍 笔者最近去面试了家游戏公司(有上市).我问他,公司有没有做微服务架构的打算及考量?他很惊讶的,我没听说过微服务耶,你可以解释一下吗? 我大概说了,方便测试,方便维护,方便升级,服务之间松耦合 ...
- Error running 'DemoApplication': No jdk for module 'demo' 没有jdk
方案1----- 按理说jdk都是在File->Project Structure里面设置就可以了,而且现在检查了也是没有问题 后来几经折腾,通过直接搜索Settings里面的jdk,发现还有这 ...
- Axis2开发webservice详解
Axis2开发webservice详解 标签: javawebserviceAxis2 2015-08-10 10:58 1827人阅读 评论(0) 收藏 举报 分类: JAVA(275) 服务器 ...
- sprignAOP那些术语
那些AOP术语 初看这么多术语,一下子都不好接受,慢慢来,很快就会搞懂.通知.增强处理(Advice) 就是你想要的功能,也就是上说的安全.事物.日志等.你给先定义好,然后再想用的地方用一下.包含As ...
- Javascript函数闭包及案例详解
什么情况下会形成闭包,什么是闭包 闭包(Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包 可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员 下面来看一个 ...
- securefx 系统中不到指定文件 (转中文)
如何处理上传工具SecureFX中的中文乱码 工具/原料 SecureFX centos7 方法/步骤 转百度知道 https://jingyan.baidu.com/article/eae07 ...
- [不止于代码]Unraid基本使用速记
1.Unraid简介 Unraid是一个虚拟机系统,类似于VM.PVE,但又区别于前二者.通过Unraid的Dokcer可以快速构建类Nas及虚拟机环境,也可虚拟黑群晖使用,可以使用磁盘阵列,保护你的 ...
- 使用GitHub Actions自动编译部署hexo博客
前言 使用hexo博客也挺久的,最开始是本地hexo clean && hexo g,最后hexo d推送到服务器.后来是本地hexo clean && hexo g, ...
- 在Docker下搭建MySQL双主双重集群(单机展示,与多机原理一致)
前言 Docker的安装部署&在Docker下MySQL的安装与配置 https://www.cnblogs.com/yumq/p/14253360.html 在Docker进行单机主从复制M ...