chore(api): upgrade graphon to v0.3.0 (#35469)

Signed-off-by: -LAN- <laipz8200@outlook.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: WH-2099 <wh2099@pm.me>
This commit is contained in:
-LAN-
2026-05-09 15:30:03 +08:00
committed by GitHub
parent f3eb3ab4dd
commit 19476109da
80 changed files with 2526 additions and 673 deletions

View File

@@ -1,7 +1,7 @@
import logging
from sqlalchemy import select, update
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select
from sqlalchemy.orm import Session, sessionmaker
from configs import dify_config
from core.errors.error import QuotaExceededError
@@ -13,6 +13,18 @@ logger = logging.getLogger(__name__)
class CreditPoolService:
@staticmethod
def _get_locked_pool(session: Session, tenant_id: str, pool_type: str) -> TenantCreditPool | None:
return session.scalar(
select(TenantCreditPool)
.where(
TenantCreditPool.tenant_id == tenant_id,
TenantCreditPool.pool_type == pool_type,
)
.limit(1)
.with_for_update()
)
@classmethod
def create_default_pool(cls, tenant_id: str) -> TenantCreditPool:
"""create default credit pool for new tenant"""
@@ -59,31 +71,57 @@ class CreditPoolService:
credits_required: int,
pool_type: str = "trial",
) -> int:
"""check and deduct credits, returns actual credits deducted"""
pool = cls.get_pool(tenant_id, pool_type)
if not pool:
raise QuotaExceededError("Credit pool not found")
if pool.remaining_credits <= 0:
raise QuotaExceededError("No credits remaining")
# deduct all remaining credits if less than required
actual_credits = min(credits_required, pool.remaining_credits)
"""Deduct exactly the requested credits or raise without mutating the pool."""
if credits_required <= 0:
return 0
try:
with sessionmaker(db.engine).begin() as session:
stmt = (
update(TenantCreditPool)
.where(
TenantCreditPool.tenant_id == tenant_id,
TenantCreditPool.pool_type == pool_type,
)
.values(quota_used=TenantCreditPool.quota_used + actual_credits)
)
session.execute(stmt)
with sessionmaker(db.engine, expire_on_commit=False).begin() as session:
pool = cls._get_locked_pool(session=session, tenant_id=tenant_id, pool_type=pool_type)
if not pool:
raise QuotaExceededError("Credit pool not found")
remaining_credits = pool.remaining_credits
if remaining_credits <= 0:
raise QuotaExceededError("No credits remaining")
if remaining_credits < credits_required:
raise QuotaExceededError("Insufficient credits remaining")
pool.quota_used += credits_required
except QuotaExceededError:
raise
except Exception:
logger.exception("Failed to deduct credits for tenant %s", tenant_id)
raise QuotaExceededError("Failed to deduct credits")
return actual_credits
return credits_required
@classmethod
def deduct_credits_capped(
cls,
tenant_id: str,
credits_required: int,
pool_type: str = "trial",
) -> int:
"""Deduct up to the available balance and return the actual deducted credits."""
if credits_required <= 0:
return 0
try:
with sessionmaker(db.engine, expire_on_commit=False).begin() as session:
pool = cls._get_locked_pool(session=session, tenant_id=tenant_id, pool_type=pool_type)
if not pool:
logger.warning("Credit pool not found, tenant_id=%s, pool_type=%s", tenant_id, pool_type)
return 0
deducted_credits = min(credits_required, pool.remaining_credits)
if deducted_credits <= 0:
return 0
pool.quota_used += deducted_credits
return deducted_credits
except QuotaExceededError:
raise
except Exception:
logger.exception("Failed to deduct capped credits for tenant %s", tenant_id)
raise QuotaExceededError("Failed to deduct credits")

View File

@@ -157,8 +157,8 @@ class DraftVarLoader(VariableLoader):
# This approach reduces loading time by querying external systems concurrently.
with ThreadPoolExecutor(max_workers=10) as executor:
offloaded_variables = executor.map(self._load_offloaded_variable, offloaded_draft_vars)
for selector, variable in offloaded_variables:
variable_by_selector[selector] = variable
for selector, offloaded_variable in offloaded_variables:
variable_by_selector[selector] = offloaded_variable
return list(variable_by_selector.values())

View File

@@ -1251,7 +1251,7 @@ class WorkflowService:
node_data = HumanInputNode.validate_node_data(adapt_human_input_node_data_for_graph(node_config["data"]))
node = HumanInputNode(
node_id=node_config["id"],
config=node_data,
data=node_data,
graph_init_params=graph_init_params,
graph_runtime_state=graph_runtime_state,
runtime=DifyHumanInputNodeRuntime(run_context),