python自学

协程化redis分布式锁实现

2018-08-21  本文已影响4人  VxCoder

最近看<<redis实战>> 里面有一个不错的redis分布式锁的实现,但是只是同步实现版本, 由于工作中用python的协程化框架,故简单改造下,代码如下:

import math
import time
import uuid
import asyncio

import aioredis
from aioredis.errors import WatchVariableError


async def acquire_lock(conn, lockname, acquire_timeout=10, lock_timeout=10):
    identifier = str(uuid.uuid4())
    lockname = 'lock:' + lockname
    lock_timeout = int(math.ceil(lock_timeout))

    end = time.time() + acquire_timeout
    while time.time() < end:
        if await conn.set(
                lockname,
                identifier,
                expire=lock_timeout,
                exist=conn.SET_IF_NOT_EXIST):
            return identifier

        await asyncio.sleep(1)

    return False


async def release_lock(conn, lockname, identifier):
    lockname = 'lock:' + lockname

    while True:

        try:
            await conn.watch(lockname)
            if await conn.get(lockname) == identifier:
                pipe = conn.multi_exec()
                pipe.delete(lockname)
                await pipe.execute()
                return True

            await conn.unwatch()
            break

        except WatchVariableError:
            pass

    return False


async def main():
    redis_pool = await aioredis.create_redis_pool(
        ("127.0.0.1", 6379),
        db=14,
        password=None,
        encoding="utf-8")

    identifier = await acquire_lock(redis_pool, 'foo_bar')
    print(await acquire_lock(redis_pool, 'foo_bar'))
    await release_lock(redis_pool, 'foo_bar', identifier)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
上一篇下一篇

猜你喜欢

热点阅读