| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package service
- import (
- "context"
- "log/slog"
- "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey"
- )
- // withGatewayProfitControlGate installs the gate only for explicitly marked
- // token requests. This keeps media, metadata, and models-list paths outside
- // the profit-control surface by construction.
- func (s *GatewayService) withGatewayProfitControlGate(ctx context.Context, groupID *int64) context.Context {
- if _, ok := gatewayTokenRequestPricingAtFromContext(ctx); !ok || groupID == nil || *groupID <= 0 {
- return ctx
- }
- if existing, ok := ctx.Value(openAIProfitControlGateCtxKey{}).(*openAIProfitControlGate); ok && existing != nil && existing.groupID == *groupID {
- return ctx
- }
- group, err := s.resolveProfitControlGroup(ctx, *groupID)
- if err != nil {
- slog.Warn("profit_control_group_load_failed", "group_id", *groupID, "error", err)
- return s.clearForeignProfitControlGate(ctx, groupID)
- }
- if group == nil || !group.ProfitControlEnabled || !profitControlPlatformSupported(group.Platform) {
- return s.clearForeignProfitControlGate(ctx, groupID)
- }
- pricingAt, _ := gatewayTokenRequestPricingAtFromContext(ctx)
- billingGroup := gatewayTokenRequestBillingGroupFromContext(ctx)
- if billingGroup == nil {
- if ctxGroup, ok := ctx.Value(ctxkey.Group).(*Group); ok && IsGroupContextValid(ctxGroup) {
- billingGroup = ctxGroup
- } else {
- billingGroup = group
- }
- }
- downstream := billingGroup.RateMultiplier
- if userID, _ := ctx.Value(ctxkey.UserID).(int64); userID > 0 {
- downstream = s.ResolveUserGroupRateMultiplier(ctx, userID, billingGroup.ID, billingGroup.RateMultiplier)
- }
- downstream *= billingGroup.PeakMultiplierAt(pricingAt)
- threshold := clampProfitControlThreshold(downstream * (1 - group.ProfitMinMargin - group.ProfitSafetyBuffer))
- gate := &openAIProfitControlGate{
- groupID: group.ID,
- platform: group.Platform,
- threshold: threshold,
- pricingAt: pricingAt,
- }
- openAIProfitControlObserverInstance.recordInstall(gate.groupID, gate.platform, gate.threshold)
- return context.WithValue(ctx, openAIProfitControlGateCtxKey{}, gate)
- }
- func (s *GatewayService) clearForeignProfitControlGate(ctx context.Context, groupID *int64) context.Context {
- existing, ok := ctx.Value(openAIProfitControlGateCtxKey{}).(*openAIProfitControlGate)
- if !ok || existing == nil || groupID == nil || existing.groupID == *groupID {
- return ctx
- }
- return context.WithValue(ctx, openAIProfitControlGateCtxKey{}, (*openAIProfitControlGate)(nil))
- }
- func (s *GatewayService) resolveProfitControlGroup(ctx context.Context, groupID int64) (*Group, error) {
- if group, ok := ctx.Value(ctxkey.Group).(*Group); ok && IsGroupContextValid(group) && group.ID == groupID {
- return group, nil
- }
- if s.schedulerSnapshot != nil {
- // Lite 读取:门只用平台/倍率/利润/高峰字段,不需要账号计数聚合。
- return s.schedulerSnapshot.GetGroupByIDLite(ctx, groupID)
- }
- return s.resolveGroupByID(ctx, groupID)
- }
- // GatewayProfitControlVetoLatest performs the terminal post-slot check against
- // the latest scheduler snapshot. Snapshot read failures are deliberately
- // fail-open to preserve availability, but are observable.
- func (s *GatewayService) GatewayProfitControlVetoLatest(ctx context.Context, selected *Account) (*Account, bool, string) {
- return profitControlVetoLatest(ctx, selected, s.schedulerSnapshot)
- }
- func profitControlVetoLatest(ctx context.Context, selected *Account, snapshot *SchedulerSnapshotService) (*Account, bool, string) {
- gate, _ := ctx.Value(openAIProfitControlGateCtxKey{}).(*openAIProfitControlGate)
- if gate == nil || selected == nil {
- return selected, false, ""
- }
- latest := selected
- if snapshot != nil {
- refreshed, err := snapshot.GetAccount(ctx, selected.ID)
- if err != nil || refreshed == nil {
- slog.Warn("profit_control_account_refresh_failed", "group_id", gate.groupID, "platform", gate.platform, "account_id", selected.ID, "error", err)
- openAIProfitControlObserverInstance.recordRefreshFailure(gate.groupID, gate.platform, gate.threshold)
- } else if !refreshed.UpdatedAt.Before(selected.UpdatedAt) {
- // 选号路径可能已做过 DB recheck,selected 比缓存快照更新鲜;只有
- // 快照不落后时才替换,避免终检把新鲜账号换回较旧的缓存对象。
- latest = refreshed
- }
- }
- vetoed, reason := openAIProfitControlVetoReason(ctx, latest)
- return latest, vetoed, reason
- }
- func (s *GatewayService) isGatewayAccountProfitEligible(ctx context.Context, account *Account) bool {
- vetoed, _ := openAIProfitControlVetoReason(ctx, account)
- return !vetoed
- }
- func gatewayProfitControlGateActive(ctx context.Context) bool {
- gate, _ := ctx.Value(openAIProfitControlGateCtxKey{}).(*openAIProfitControlGate)
- return gate != nil
- }
|