⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠ You can decompress Drawing data with the command palette: ‘Decompress current Excalidraw file’. For more info check in plugin settings under ‘Saving’
Excalidraw Data
Text Elements
Batch pre-check: CanAllow()
(Transport) GAS / Spex | | cmd: voucher.ss.distribution.batch_distribute_voucher v (Generated Spex dispatcher) _Distribution_BatchDistributeVoucherHandler(ctx, req, resp) → DistributionServiceImpl.BatchDistributeVoucher(ctx, req, resp) v (Handler entry) handler.BatchDistributeVoucher(ctx, req) - validateBatchReq(req.Requests) - distributeService.BatchDistribute(ctx, region, infos) v (Distribute orchestration) distribute.Service.BatchDistribute(ctx, region, infos) - steps := [checkRateLimitAvailability, checkUserExistence, loadVouchers, …] - meta := batchDistribute(ctx, region, infos, steps) v (Step execution) ExecuteSteps(ctx, meta, steps) → step#1 checkRateLimitAvailability(meta)(ctx) - userIDs := extractUserIDs(meta) - errs := batchCanAllow(ctx, userIDs) - fillErrorToResult(meta.results, errs) (results[i].Errs filled ⇒ this item will NOT continue) | v batchCanAllow(ctx, userIDs) for each userID: canAllow(ctx, userID) → rateLimiter.CanAllow(ctx, strconv(uid)) → ShadowAwareLimiter.CanAllow(ctx, key) → pick(normal vs shadow by shadow.IsShadow(ctx)) → InadaptiveDistrLimiter.CanAllow(ctx, key) → Redis EVAL(inadaptiveCanAllowNLua) - GET key only - returns wait time (no mutation)
Pre-item check: Allow()
(Transport) GAS / Spex | v (Generated Spex dispatcher) _Distribution_BatchDistributeVoucherHandler → DistributionServiceImpl.BatchDistributeVoucher v (Handler entry) handler.BatchDistributeVoucher → distributeService.BatchDistribute(ctx, region, infos) v (Distribute orchestration) BatchDistribute(…) - meta := ExecuteSteps(…) // Path A already ran here - for each i where meta.results[i].Errs is empty: distributeOneBasic(ctx, region, info, voucher, campaign, result, isRandomCode) - lock(ctx, userID, voucherID) - checkUserVoucherDuplicate(…) - allow(ctx, userID) → rateLimiter.Allow(ctx, strconv(uid)) → ShadowAwareLimiter.Allow(ctx, key) → pick(normal vs shadow by shadow.IsShadow(ctx)) → InadaptiveDistrLimiter.Allow(ctx, key) → Redis EVAL(inadaptiveAllowNLua) - GET key - if allowed: SETEX key TTL value (mutates) - returns 0 (or wait time) - distributeOneUserVoucher(…) - unlock(…)