# -*- coding: utf-8 -*-
"""
@File    : test_redis_lock.py
@Author  : Jay
@Date    : 2026/3/19 15:39
@Desc    : 测试 AsyncRedisAtomicMultiLock 分布式锁功能

组合锁：所有 KEYS 都要同时不存在或被删除，才认为锁释放
单键锁：单个 KEY 被删除即释放锁
"""

from redis_xsync import register_redis, resolve_redis

if __name__ == "__main__":
    import threading, asyncio

    cfg = {
        'host': '127.0.0.1',
        'port': 6379,
        'db': 0,
        'password': '',
        'decode_responses': True
    }
    cx = 0
    redisXsync = register_redis(label='redis_xsync', **cfg)
    AsyncRedisAtomicMultiLock = redisXsync.AsyncRedisAtomicMultiLock

    register_redis(label='redis_xsync2', **cfg)
    AsyncRedisAtomicMultiLock2 = resolve_redis("redis_xsync2").AsyncRedisAtomicMultiLock


    # 异步协程
    def thread_target():
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(async_example())
        loop.close()


    async def async_example():
        global cx
        while True:
            try:
                async with AsyncRedisAtomicMultiLock2("lock2", db=0, ttl_ms=2000, blocking=True):
                    # async with redisXsyn cas r: # 或者也可以使用默认 db
                    async with redisXsync(db=3) as r:
                        await r.setnx(f"db-async", str(cx))
                        cx += 1
                        await asyncio.sleep(.5)
                        print(f"{cx=}")
            except:
                pass


    def sync_example():
        global cx
        while True:
            try:
                with AsyncRedisAtomicMultiLock2("lock2", db=0, ttl_ms=2000, blocking=True):
                    with redisXsync(db=2) as r:
                        r.setnx("db2", str(cx))
                        cx += 1
                        print(f"{cx=}")

                    with redisXsync(db=3) as r:
                        r.setnx("db3", str(cx))
                        cx += 1
                        print(f"{cx=}")
            except:
                pass


    # 同步线程
    for _ in range(3):
        threading.Thread(target=sync_example).start()

    # threading.Thread(target=thread_target).start()

    # asyncio.run(async_example())
