cc-async-task-pattern

Implements asynchronous task state machines for long-running Spring backend operations.

1.0k|109|Updated Jan 4, 2026
One-click install
npx skills add https://github.com/doccker/cc-use-exp --skill cc-async-task-pattern
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: cc-async-task-pattern
Source: https://github.com/doccker/cc-use-exp/tree/main/.codex/skills/cc-async-task-pattern
Command: npx skills add https://github.com/doccker/cc-use-exp --skill cc-async-task-pattern

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Synchronous API endpoints that run longer than 10 seconds get cut off by gateway timeouts (30s), causing 502/504 errors, duplicate user clicks triggering concurrent executions, unbounded in-memory state caches leaking memory, and lost tenant context in child threads.

Core Features & Use Cases

  • Async State Machine Template: Provides a standard triggerAsync() + getStatus() pattern using ConcurrentHashMap and Executor so trigger endpoints return immediately while work runs in the background.
  • Defensive Trap Coverage: Addresses five concrete failure modes: gateway timeout truncation, unbounded state cache growth (with TTL/LRU eviction strategies), lost TenantContext/SecurityContext/MDC in child threads, duplicate concurrent triggers, and frontend double-polling conflicts.
  • Frontend UX & Review Checklists: Defines polling behavior, button states, progress display, and a code review checklist for any new async task.
  • Use Case: A 6000-row product duplicate-check that previously timed out at 30s is converted into a tenant-isolated async job with status polling, TTL-based state cleanup, and duplicate-trigger rejection.

Quick Start

Ask the AI to refactor the slow duplicate-check endpoint into an async trigger-plus-status polling pattern following this skill's template.

Frequently Asked Questions about cc-async-task-pattern

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I handle API requests that take longer than 30 seconds in Spring?

Split the endpoint into a trigger method that starts background work via an Executor and returns immediately, plus a status endpoint the frontend polls. Store task state in a ConcurrentHashMap keyed by tenant with RUNNING, SUCCESS, and FAILED statuses.

How to prevent duplicate concurrent task execution when users click a button twice?

Check the state cache before starting: if a RUNNING state already exists for the tenant, return its snapshot instead of launching a new task. On the frontend, disable the trigger button while status is RUNNING.

Why does TenantContext become null in async child threads?

ThreadLocal values do not propagate to threads spawned by an Executor. Capture the tenant ID before submitting the task, then set it inside the child thread's run method and clear it in a finally block.

How do I prevent memory leaks from in-memory task state caches?

Apply a TTL eviction strategy: on every trigger or status call, remove non-RUNNING entries whose finishedAt timestamp is older than one hour. For large states, use Caffeine with maximumSize and expireAfterWrite, or store results in Redis.

When should I use a message queue instead of ConcurrentHashMap async tasks?

The in-memory state machine fits single-instance deployments with tasks under one hour. Move to Redis with distributed locks for multi-instance deployments, and to Spring Batch, XXL-Job, or RocketMQ for tasks over an hour or requiring retries.