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的更多相关文章

  1. collections 模块(namedtuple, deque, Counter )

    基本介绍 我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型 ...

  2. Python_Day_05 计数器(counter),有序字典(OrderDict),默认字典(defaultdict),可命名元祖(namedtuple),双向队列(deque),单项队列(deuqe.Queue)

    Counter(计数器) 是一个字典的子类,存储形式同样为字典,其中存储的键为字典的元素,值为元素出现的次数,在使用之前我们需要先导入文件 import collections 初始化一个计数器 im ...

  3. 计数器(counter),有序字典(OrderDict),默认字典(defaultdict),可命名元祖(namedtuple),双向队列(deque),单项队列(deuqe.Queue)

    Python_Day_05 计数器(counter),有序字典(OrderDict),默认字典(defaultdict),可命名元祖(namedtuple),双向队列(deque),单项队列(deuq ...

  4. 再谈collections模块defaultdict()和namedtuple()

    defaultdict()和namedtuple()是collections模块里面2个很实用的扩展类型.一个继承自dict系统内置类型,一个继承自tuple系统内置类型.在扩展的同时都添加了额外的很 ...

  5. Python namedtuple

    我们都知道Python中的tuple是一个非常高效的集合对象,但是我们只能通过索引的方式访问这个集合中的元素,比如下面的代码: Bob=('bob',30,'male') print'Represen ...

  6. Python元类实践--自己定义一个和collections中一样的namedtuple

    大家可能很熟悉在collections模块中有一个很好用的扩展数据类型-namedtuple. 如果你还不知道这个类型,那么请翻看标准手册. 我利用元类轻松定义一个namedtuple. 先把代码贴上 ...

  7. python:学习defaultdict,namedtuple

    # -*- coding: utf-8 -*-__author__ = 'Administrator'import bisect#排序说明:http://en.wikipedia.org/wiki/i ...

  8. collection系列用法-namedtuple()

    namedtuple() 参考文章地址:http://www.cnblogs.com/herbert/p/3468294.html namedtuple是继承自tuple的子类.namedtuple和 ...

  9. python-Day3-set 集合-counter计数器-默认字典(defaultdict) -可命名元组(namedtuple)-有序字典(orderedDict)-双向队列(deque)--Queue单项队列--深浅拷贝---函数参数

    上节内容回顾:C语言为什么比起他语言块,因为C 会把代码变异成机器码Pyhton 的 .pyc文件是什么python 把.py文件编译成的.pyc文件是Python的字节码, 字符串本质是 字符数组, ...

  10. python中的collections.namedtuple

    简介 collections.namedtuple是一个工厂方法,它可以动态的创建一个继承tuple的子类.跟tuple相比,返回的子类可以使用名称来访问元素. 使用方法 用一个例子来介绍: > ...

随机推荐

  1. MySQL 5.6.38安装

    #1.安装说明 本套安装方式适用于:CentOS6.X 或CentOS7.X系列的OS安装,此方法适用于MySQL5.6.xx版本的安装,如果是5.7版本的话不适合该配置. #2.准备安装环境 # N ...

  2. 安装篇八:配置 Nginx 使其支持 MySQL 应用

    配置说明 (让nginx  MySQL(中间件)之间建立关系) 第一个里程: 编写nginx.php首页文件 第二个里程:重启nginx 第三个里程:访问网页测试 打开浏览器访问:http://47. ...

  3. 为什么线程安全的List推荐使用CopyOnWriteArrayList,而不是Vector

    注:本系列文章中用到的jdk版本均为java8 相比很多同学在刚接触Java集合的时候,线程安全的List用的一定是Vector.但是现在用到的线程安全的List一般都会用CopyOnWriteArr ...

  4. 支付业务优化else if 代码

    背景 最近在做项目的时候,需要接入支付.由于接入第三方支付而且还不知止一家,需要接入很多家.比如说支付宝.微信.富友支付等.每家支付都一个回调.现如今的代码,根据不同的第三方支付一大堆else if判 ...

  5. ArrayList之SubList源码解析

    subList是ArrayList的内部类, public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck( ...

  6. 使用swagger上传文件

    经常使用swagger,可以通过设置[ProducesResponseType]标记接口的返回信息:swagger也能通过接口的参数列表,自动获得发送的数据结构信息. 不过有一个例外,就是上传文件的时 ...

  7. 隐语义模型LFM

      隐语义模型是通过隐含特征,联系用户和物品,基于用户的特征对物品进行自动聚类,然后在用户感兴趣的类中选择物品推荐给用户. 对于推荐系统,常用的算法: USER-CF:给用户推荐和他兴趣相似的用户喜欢 ...

  8. [LeetCode]92. Reverse Linked List II反转部分链表

    /* 重点还是反转链表 思路就是中间的反转,然后两头接上 */ public ListNode reverseBetween(ListNode head, int m, int n) { if (he ...

  9. KafkaProducer 简析

    使用方式 KafkaProducer 发送消息主要有以下 3 种方式: Properties properties = new Properties(); properties.setProperty ...

  10. 基于Let's Encrypt生成免费证书-支持多域名泛域名证书

    目录 客户端 certbot acme.sh 安装acme.sh 1. 自动安装 2. 手动安装 3. 测试收否安装成功 使用acme.sh生成证书 1. HTTP 方式 2. DNS 方式 1. 生 ...