Skip to content

Commit 52376ed

Browse files
committed
Enhanced logging
1 parent 2dd18ea commit 52376ed

File tree

1 file changed

+80
-7
lines changed

1 file changed

+80
-7
lines changed

acapy_agent/anoncreds/revocation.py

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def __init__(self, lock_key: str):
6868
self.lock_key = lock_key
6969
self.lock_value = None
7070
self._redis = None
71+
self.acquired_at = None # NEW: Track acquisition time
7172

7273
async def _get_redis(self):
7374
if self._redis is None:
@@ -77,33 +78,105 @@ async def _get_redis(self):
7778
async def __aenter__(self):
7879
redis_client = await self._get_redis()
7980
self.lock_value = str(uuid4())
81+
attempt_count = 0
82+
start_time = time.time()
83+
84+
# NEW: Initial logging
85+
LOGGER.info(
86+
"Attempting to acquire lock '%s' with value '%s'",
87+
self.lock_key,
88+
self.lock_value
89+
)
8090

81-
# Keep trying to acquire the lock
8291
while True:
92+
attempt_count += 1
8393
acquired = await redis_client.set(
8494
self.lock_key,
8595
self.lock_value,
86-
nx=True, # Only set if key doesn't exist
87-
ex=30 # 30s timeout
96+
nx=True,
97+
ex=30
8898
)
8999
if acquired:
100+
self.acquired_at = time.time()
101+
# NEW: Success logging with metrics
102+
LOGGER.info(
103+
"Lock '%s' acquired successfully by '%s' after %d attempts in %.2f seconds",
104+
self.lock_key,
105+
self.lock_value,
106+
attempt_count,
107+
self.acquired_at - start_time
108+
)
90109
break
91-
await asyncio.sleep(0.1)
110+
111+
# NEW: Timeout protection (prevents infinite waiting)
112+
elapsed = time.time() - start_time
113+
if elapsed > 25: # 25 second timeout (5s buffer before Redis expires lock)
114+
LOGGER.error(
115+
"Failed to acquire lock '%s' after %.2f seconds and %d attempts - timeout exceeded",
116+
self.lock_key,
117+
elapsed,
118+
attempt_count
119+
)
120+
raise AnonCredsRevocationError(
121+
f"Timeout waiting for lock '{self.lock_key}' after {elapsed:.2f} seconds"
122+
)
123+
124+
# NEW: Periodic progress logging
125+
if attempt_count % 50 == 0: # Log every 5 seconds
126+
LOGGER.warning(
127+
"Still waiting for lock '%s' after %d attempts (%.2f seconds)",
128+
self.lock_key,
129+
attempt_count,
130+
elapsed
131+
)
132+
133+
await asyncio.sleep(0.5)
92134

93135
return self
94136

95137
async def __aexit__(self, exc_type, exc_val, exc_tb):
96138
if self.lock_value and self._redis:
97-
# Lua script to safely release only if we own the lock
98139
lua_script = """
99140
if redis.call("GET", KEYS[1]) == ARGV[1] then
100141
return redis.call("DEL", KEYS[1])
101142
else
102143
return 0
103144
end
104145
"""
105-
await self._redis.eval(lua_script, 1, self.lock_key, self.lock_value)
106-
await self._redis.close()
146+
try:
147+
result = await self._redis.eval(lua_script, 1, self.lock_key, self.lock_value)
148+
held_duration = time.time() - self.acquired_at if self.acquired_at else 0
149+
150+
# NEW: Release logging with duration tracking
151+
if result == 1:
152+
LOGGER.info(
153+
"Lock '%s' released successfully by '%s' after being held for %.2f seconds",
154+
self.lock_key,
155+
self.lock_value,
156+
held_duration
157+
)
158+
else:
159+
# NEW: Warning for expired locks
160+
LOGGER.warning(
161+
"Lock '%s' was already expired or released. Expected value '%s', held for %.2f seconds",
162+
self.lock_key,
163+
self.lock_value,
164+
held_duration
165+
)
166+
except Exception as e:
167+
# NEW: Error handling for release failures
168+
LOGGER.error(
169+
"Error releasing lock '%s' with value '%s': %s",
170+
self.lock_key,
171+
self.lock_value,
172+
str(e)
173+
)
174+
finally:
175+
try:
176+
await self._redis.close()
177+
LOGGER.info("Redis connection closed for lock '%s'", self.lock_key)
178+
except Exception as e:
179+
LOGGER.error("Error closing Redis connection: %s", str(e))
107180

108181
_credential_creation_lock = AsyncRedisLock("acapy_credential_creation_lock")
109182

0 commit comments

Comments
 (0)