mirror of
https://github.com/langgenius/dify.git
synced 2026-02-25 12:16:29 +08:00
62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
"""
|
|
Celery task for updating API token last_used_at timestamp asynchronously.
|
|
"""
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
|
|
from celery import shared_task
|
|
from sqlalchemy import update
|
|
from sqlalchemy.orm import Session
|
|
|
|
from extensions.ext_database import db
|
|
from libs.datetime_utils import naive_utc_now
|
|
from models.model import ApiToken
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@shared_task(queue="dataset", bind=True, max_retries=3)
|
|
def update_api_token_last_used_task(self, token: str, scope: str | None, start_time_iso: str):
|
|
"""
|
|
Asynchronously update the last_used_at timestamp for an API token.
|
|
|
|
Uses timestamp comparison to ensure only updates when last_used_at is older
|
|
than the request start time, providing natural concurrency control.
|
|
|
|
Args:
|
|
token: The API token string
|
|
scope: The token type/scope (e.g., 'app', 'dataset')
|
|
start_time_iso: ISO format timestamp of when the request started
|
|
"""
|
|
try:
|
|
# Parse start_time from ISO format
|
|
start_time = datetime.fromisoformat(start_time_iso)
|
|
# Update database
|
|
current_time = naive_utc_now()
|
|
|
|
with Session(db.engine, expire_on_commit=False) as session:
|
|
update_stmt = (
|
|
update(ApiToken)
|
|
.where(
|
|
ApiToken.token == token,
|
|
ApiToken.type == scope,
|
|
(ApiToken.last_used_at.is_(None) | (ApiToken.last_used_at < start_time)),
|
|
)
|
|
.values(last_used_at=current_time)
|
|
)
|
|
result = session.execute(update_stmt)
|
|
|
|
if hasattr(result, "rowcount") and result.rowcount > 0:
|
|
session.commit()
|
|
logger.info("Updated last_used_at for token (async): %s... (scope: %s)", token[:10], scope)
|
|
return {"status": "updated", "rowcount": result.rowcount, "start_time": start_time_iso}
|
|
else:
|
|
logger.debug("No update needed for token: %s... (already up-to-date)", token[:10])
|
|
return {"status": "no_update_needed", "reason": "last_used_at >= start_time"}
|
|
|
|
except Exception as e:
|
|
logger.warning("Failed to update last_used_at for token (async): %s", e)
|
|
# Don't retry on failure to avoid blocking the queue
|
|
return {"status": "failed", "error": str(e)}
|