Increments the usage count for a specific profile. This function is async and thread-safe via asyncio.Lock.
(profile_path: str, tokens: int)
| 34 | |
| 35 | |
| 36 | async def increment_profile_usage(profile_path: str, tokens: int) -> None: |
| 37 | """ |
| 38 | Increments the usage count for a specific profile. |
| 39 | This function is async and thread-safe via asyncio.Lock. |
| 40 | """ |
| 41 | if not profile_path or not os.path.exists(profile_path): |
| 42 | return |
| 43 | |
| 44 | # Normalize path to ensure consistency as key |
| 45 | profile_path = os.path.abspath(profile_path) |
| 46 | |
| 47 | async with _USAGE_LOCK: |
| 48 | usage_data = _load_usage_data() |
| 49 | |
| 50 | # Smart path reconciliation: Check if we have data for this file under a different path |
| 51 | target_key = profile_path |
| 52 | if profile_path not in usage_data: |
| 53 | profile_basename = os.path.basename(profile_path) |
| 54 | for key in list(usage_data.keys()): |
| 55 | if os.path.basename(key) == profile_basename: |
| 56 | # Found a match by filename! Migrate the data to the new path |
| 57 | logger.info( |
| 58 | f"Migrating usage data for '{profile_basename}' from '{key}' to '{profile_path}'" |
| 59 | ) |
| 60 | usage_data[profile_path] = usage_data.pop(key) |
| 61 | target_key = profile_path |
| 62 | break |
| 63 | |
| 64 | current_usage = usage_data.get(target_key, 0) |
| 65 | usage_data[target_key] = current_usage + tokens |
| 66 | _save_usage_data(usage_data) |
| 67 | logger.debug( |
| 68 | f"Updated usage for {os.path.basename(profile_path)}: +{tokens} tokens (Total: {usage_data[target_key]})" |
| 69 | ) |
| 70 | |
| 71 | |
| 72 | def get_profile_usage(profile_path: str) -> int: |
no test coverage detected