在 pickle 序列化异常的情况下返回值而不是整个调用失败

问题描述 投票:0回答:0
from dogpile.cache import make_region

TIMEOUT_SECONDS = 10 * 60


def my_key_generator(namespace, fn):
    fname = fn.__name__

    def generate_key(*arg):
        key_template = fname + "_" + "_".join(str(s) for s in arg)
        return key_template

    return generate_key


region = make_region(function_key_generator=my_key_generator).configure(
    "dogpile.cache.redis",
    expiration_time=TIMEOUT_SECONDS,
    arguments={
        "host": "localhost",
        "port": 6379,
        "db": 0,
        "redis_expiration_time": TIMEOUT_SECONDS * 2,  # 2 hours
        "distributed_lock": True,
        "thread_local_lock": False,
    },

)


@region.cache_on_arguments()
def load_user_info(user_id):
    log.info(f"Called func {user_id}")
    return lambda: user_id

print(load_user_info(1))

这将返回预期的 pickle 错误。

Traceback (most recent call last):
  File "/Users/user/src/python-test/dogpile-test.py", line 120, in <module>
    print(load_user_info(1))
          ^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/cache/region.py", line 1577, in get_or_create_for_user_func
    return self.get_or_create(
           ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/cache/region.py", line 1042, in get_or_create
    with Lock(
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/lock.py", line 185, in __enter__
    return self._enter()
           ^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/lock.py", line 94, in _enter
    generated = self._enter_create(value, createdtime)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/lock.py", line 178, in _enter_create
    return self.creator()
           ^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/cache/region.py", line 1012, in gen_value
    self._set_cached_value_to_backend(key, value)
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/cache/region.py", line 1288, in _set_cached_value_to_backend
    key, self._serialized_cached_value(value)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/cache/region.py", line 1258, in _serialized_cached_value
    return self._serialize_cached_value_elements(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/dogpile/cache/region.py", line 1232, in _serialize_cached_value_elements
    serializer(payload),
    ^^^^^^^^^^^^^^^^^^^
AttributeError: Can't pickle local object 'load_user_info.<locals>.<lambda>'

我的问题是 dogpile 有没有办法捕获 pickle 异常,记录异常并返回实际值而不是使实际函数调用失败?

python pickle dogpile.cache
© www.soinside.com 2019 - 2024. All rights reserved.