从LockError中删除redis-py Lock名称?

suzh9iv8  于 2023-11-16  发布在  Redis
关注(0)|答案(1)|浏览(138)

我有一个应用程序经常使用redis.lock.Lock(来自官方的redis-py软件包)。它要么被我正在开发的软件直接使用,要么被其他软件包使用。在极少数情况下,我最终会使用LockError(例如,如果应用程序被错误地重新启动)。
我设法捕获了这些Exceptions,但在可用的属性中,只有错误消息,而没有Lock的名称(这将允许我执行清理任务)。
有没有办法向LockError对象添加信息,或者如何从within except块中找到Lock名称(请记住,我不能修改Lock实现,也不能创建继承它的类,因为它可能是从我不拥有的代码示例化的)?
代码示例:

try:
  do_many_things_with_many_locks()
except LockError as le:
  # How to retrieve which lock failed?

字符串

yhived7q

yhived7q1#

由于不能子类化和修改Lock实现,因此可以内省异常并从Lock对象中检索名称。

import inspect

def getlockname(error):
    # This is the frame before the error was raised.
    frame_info = inspect.trace(context=1).pop()
    # We can get Lock instance in the locals in that frame
    lock = inspect.getargvalues(frame_info.frame).locals['self']
    return lock.name

字符串
比如说,

class LError(Exception):
    pass

class LOErrorWhenAcquired:
    def __init__(self):
        self.name = "foo"
      
    def __enter__(self):
        if self.acquire():
            return self
        raise LError("failed")
  
    def acquire(self):
        return False

    def release(self):
        pass
    
    def __exit__(self):
        pass
    
class LOErrorWhenReleased:
    def __init__(self):
        self.name = "foo"
      
    def __enter__(self):
        if self.acquire():
            return self
      
    def acquire(self):
        return True
  
    def release(self):
        raise LError("failed")

    def __exit__(self, *args):
        self.release()

try:
    with LOErrorWhenAcquired() as wa:
        pass
except LError as e:
    print(getlockname(e))

try:
    with LOErrorWhenReleased() as wr:
        pass
except LError as e:
    print(getlockname(e))

相关问题