如何在python中使通过上下文管理器发布的资源失效?

2024-05-13 07:13:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我的问题与Kazoo/Zookeeper有关,但更一般地说,它是关于分配一个资源,然后让该资源的调用者不应该暂停。来自Kazoo docs:

It’s highly recommended to add a state listener with add_listener() and watch for LOST and SUSPENDED state changes and re-act appropriately. In the event that a LOST state occurs, its certain that the lock and/or the lease has been lost.

我正在使用上下文管理器分配锁:

@contextmanager
def lock(self, path, identifier):
  lock = zk.Lock(path, identifier)
  lock.acquire()
  yield lock      <--- how to communicate connection loss from client?
  finally: 
    lock.release()

用法如下:

with lock('/some_op/') as lck:
  # do something with lock, but pause in case of connection loss? 

在连接丢失的情况下,如何分配锁但撤消访问?

Kazoo建议您如何实现connection state listener

def my_listener(state):
    if state == KazooState.LOST:
        # Register somewhere that the session was lost
    elif state == KazooState.SUSPENDED:
        # Handle being disconnected from Zookeeper
    else:
        # Handle being connected/reconnected to Zookeeper

Tags: andthetoaddlockthatwith资源
1条回答
网友
1楼 · 发布于 2024-05-13 07:13:57

这可能不是最佳设计,但您可以提供对with语句主体的锁的引用:

@contextmanager
def acquire_lock(self, path, identifier):
  lock = zk.Lock(path, identifier)
  try: 
    retry = KazooRetry()
    retry(lock.acquire)
    yield lock
  finally: 
    lock.release()

with acquire_lock('/some_op/') as lock:
    ...
    if necessary:
        lock.release()
    ...

具体到您的问题(我不熟悉Kazoo),您可以在上下文管理器中定义my_listener,在这里它可以关闭锁。你知道吗

@contextmanager
def acquire_lock(self, path, identifier):
    lock = zk.Lock(path, identifier)
    def my_listener(state):
        if state == KazooState.LOST:
            lock.release()
        elif state == KazooState.SUSPENDED:
            ...

    try:
        retry = KazooRetry()
    # etc

您的上下文可能需要生成侦听器,或者注册它(或者您对侦听器所做的任何操作),但是无论您对它所做的任何操作,它都可以访问您在上下文管理器中创建的锁。你知道吗

相关问题 更多 >