iflytek/astron-agent · warning · IllegalStateException

Distributed lock acquisition timeout, please try again later

Error message

Distributed lock acquisition timeout, please try again later

What it means

BotServiceImpl wraps bot create/update operations in executeWithLock, a Redisson distributed lock (tryLock with 5s wait, 10s lease). If the lock cannot be acquired within 5 seconds, it throws this IllegalStateException so concurrent mutations of the same bot don't race. It signals contention, not corruption.

Solutions

  1. Retry the request after a short delay — the error message explicitly says to try again later; add client-side backoff on this status.
  2. Disable the save/submit button and deduplicate in-flight requests on the frontend to prevent concurrent mutation of the same bot.
  3. Verify Redisson/Redis connectivity and latency; slow lock acquisition often indicates Redis health issues.
  4. If updates routinely exceed 5s, profile the operation or increase the waitTime in executeWithLock's tryLock call.

Example fix

// before: fire-and-forget submit triggers duplicate updates
await updateBot(data);
// after: serialize per-bot updates and retry on lock timeout
try {
  await updateBot(data);
} catch (e) {
  if (isLockTimeout(e)) await retryWithBackoff(() => updateBot(data), { retries: 3, baseMs: 500 });
  else throw e;
}
Defensive patterns

Strategy: retry

Try / catch

try { await updateBot(data); } catch (e) { if (e.code === 'LOCK_TIMEOUT' || /lock acquisition timeout/.test(e.message)) { await sleep(1000); return retry(); } throw e; }

Prevention

When it happens

Trigger: Calling insertWorkflowBot, insertBotBasicInfo, updateWorkflowBot, or updateBotBasicInfo for a bot whose lockKey is already held by another thread/instance for more than 5 seconds — e.g. double-clicked save buttons, two concurrent requests for the same bot, or a previous holder that is stuck in a slow DB/Redis operation beyond the 10s lease.

Common situations: Users double-submitting the create/update form; retry storms after a slow response; long-running updates blocking subsequent requests; Redis latency making lock acquisition slow; deployments where a request thread stalls holding the lock.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/4dc084cdeb7aeaac. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/commons/src/main/java/com/iflytek/astron/console/commons/service/bot/impl/BotServiceImpl.java:303

        userLangChainLogService.insertUserLangChainLog(userLangChainLog);
        UserLangChainInfo userLangChainInfo = UserLangChainInfo.builder()
                .id(Long.parseLong(botId.toString()))
                .botId(Integer.parseInt(botId.toString()))
                .maasId(data.getLong("id"))
                .flowId(data.getString("flowId"))
                .uid(uid)
                .spaceId(spaceId)
                .updateTime(LocalDateTime.now())
                .build();
        userLangChainDataService.insertUserLangChainInfo(userLangChainInfo);
    }

    private <T> T executeWithLock(String lockKey, java.util.function.Supplier<T> operation) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            boolean acquired = lock.tryLock(5, 10, TimeUnit.SECONDS);
            if (!acquired) {
                throw new IllegalStateException("Distributed lock acquisition timeout, please try again later");
            }
            return operation.get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Thread interrupted while acquiring lock", e);
        } catch (Exception e) {
            log.error("Operation failed with lock: {}", lockKey, e);
            throw e;
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    private void validateBotCreation(String uid, String botName, Long spaceId) {
        if (chatBotDataService.checkRepeatBotName(uid, null, botName, spaceId)) {
            throw new BusinessException(ResponseEnum.DUPLICATE_BOT_NAME);

View on GitHub (pinned to 5e758547a8)