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相比,返回的子类可以使用名称来访问元素. 使用方法 用一个例子来介绍: > ...
随机推荐
- 使用ajax请求上传多个或者多个附件
jsp页面 <%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML> ...
- Windows Terminal 新手入门
翻译自 Kayla Cinnamon 2020年12月17日的文章<Getting Started with Windows Terminal> [1] 安装 Windows Termin ...
- MySQL不会丢失数据的秘密,就藏在它的 7种日志里
本文收录在 GitHub 地址 https://github.com/chengxy-nds/Springboot-Notebook 进入正题前先简单看看MySQL的逻辑架构,相信我用的着. MySQ ...
- vue-cli3 创建项目路由缺失问题
1.在项目中新建一个router.js router.js import Vue from 'vue' import Router from 'vue-router' import Home from ...
- vue中的一些用法,持续更新中......
1.跳转用法 @1.在template模板中通常使用router-link to='url' @2.在js中 1.this.$router.push({path: ''/order/index''}) ...
- 树莓派(4B)新手入门教程
前期准备 必要物料 树莓派4B 主机 Type-C 电源 内存卡(8G+) 一般建议一步到位64G 系统镜像 镜像写入工具 下载地址 镜像下载 官方下载地址: https://www.raspberr ...
- Linux常用命令 | grep
作者简介 李先生(Lemon),高级运维工程师(自称),SRE专家(目标),梦想在35岁买一辆保时捷.喜欢钻研底层技术,认为底层基础才是王道.一切新技术都离不开操作系统(CPU.内存.磁盘).网络 ...
- 查找linux系统下的端口被占用进程的两种方法 【转】
在linux下开发时,你的软件可能要使用某一个端口,或者想查找某一个端口是否被占用.需要怎么做呢??这的确是一个比较烦恼的问题,我也此为这个苦恼过.但是通过查找man手册,还是同事的交流.总结出来两种 ...
- dhcp分发地址以及静态路由设置
路由器R1配置: system-view [Huawei]sysname R1 [R1]user-interface console 0 [R1-ui-console0]idle-timeout 0 ...
- python的默认参数的一个坑
前言 pass 正文 在 https://docs.python.org/3/tutorial/controlflow.html#default-argument-values 中,有这样一段话 Im ...