基于zookeeper的分布式Lock及RLock的实现

假如想象 提交于 2021-01-03 15:39:43

一.Lock and RLock

需要zookeeper的python 客户端kazoo

# -*- coding: utf-8 -*-
import os
import uuid

from kazoo.client import KazooClient
from kazoo.recipe.lock import Lock


class ZkLock(object):
    def __init__(self,lockname,zkhosts,basepath='/locks',logger=None,timeout=5):

        self._zk_hosts = zkhosts
        #
        self._client = KazooClient(hosts=self._zk_hosts,logger=logger,timeout=timeout)

        self._zk_path = os.path.join(basepath,lockname)
        self._lock_handle = Lock(self._client,self._zk_path)

    def start(self):
        self._client.start()

    def stop(self):
        self._client.stop()

    def acquire(self, blocking=True, timeout=None):
        self.start()
        return self._lock_handle.acquire(blocking=blocking, timeout=timeout)

    def release(self):
        return self._lock_handle.release()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.release()

class ZkRLock(ZkLock):
    def __init__(self, lockname, basepath='/locks', zkhosts=None, timeout=5):
        super(ZkRLock,self).__init__(lockname=lockname, basepath=basepath, zkhosts=zkhosts, timeout=timeout)
        # self._is_acquired  = False
        self._token = uuid.uuid4().hex
        self.__owner = None
        self.__count = 0

    def acquire(self,blocking=True, timeout=None):
        if self.__owner == self._token:
            self._is_acquired = True
            self.__count += 1
            return True

        self.start()
        rc = self._lock_handle.acquire(blocking=blocking,timeout=timeout)

        if rc:
            self.__owner = self._token
            self.__count = 1
        return rc

    def release(self):
        # if self.__owner != self._token:
        #     raise RuntimeError("cannot release un-acquired lock")

        self.__count -= 1
        if not self.__count:
            self.__owner = None
            return self._lock_handle.release()


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!