name: async-worker-pipeline description: "Slack Path 2: Background Workers. Implements Producer/Consumer pattern with Redis." version: 1 vars: project_name: "" feature_slug: "async-jobs" steps: # --- Infrastructure --- create-project: action: api method: POST endpoint: /project body: name: "{{ .vars.project_name }}" description: "Slack Path 2: Async Workers" outputs: - project_id: .data.name - domain: .data.domain add-redis: description: Add Redis for job queue depends_on: [create-project] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components" body: type: redis name: "job-queue" add-api: description: Public API (Producer) depends_on: [add-redis] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components" body: type: service name: "api" add-worker: description: Worker Service (Consumer) depends_on: [add-redis] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components" body: type: worker name: "background-processor" wait-infra: action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" # --- Implementation --- implement-queue: description: "Agent implements Job Queue logic in API and Worker" depends_on: [wait-infra] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/implement-feature {{ .vars.feature_slug }} --requirements 'API: POST /jobs pushes JSON to Redis. Worker: Pops from Redis, simulates work, updates status. API: GET /jobs/{id} returns status.'" auto_commit: true auto_push: true git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git" outputs: - build_id: .data.task_id wait-code: action: shell command: | for i in {1..120}; do STATUS=$(curl -s "$RDEV_API_URL/builds/{{ .outputs.implement-queue.build_id }}" -H "X-API-Key: $RDEV_API_KEY" | jq -r '.data.status // .status') if [ "$STATUS" == "completed" ]; then exit 0; fi if [ "$STATUS" == "failed" ]; then exit 1; fi sleep 5 done exit 1 wait-deploy: action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" # --- Verification --- verify-async: description: "Create Job -> Verify Acceptance -> Poll for Completion" depends_on: [wait-deploy] action: shell command: | DOMAIN="{{ .outputs.create-project.domain }}" # 1. Enqueue JOB_ID=$(curl -s -X POST "https://$DOMAIN/api/jobs" -d '{"type":"image_resize"}' | jq -r .id) echo "Job enqueued: $JOB_ID" # 2. Poll for completion (Worker should pick it up) for i in {1..10}; do STATUS=$(curl -s "https://$DOMAIN/api/jobs/$JOB_ID" | jq -r .status) echo "Job status: $STATUS" if [ "$STATUS" == "completed" ]; then exit 0; fi sleep 2 done echo "Job never completed" exit 1 teardown: - action: api method: DELETE endpoint: "/project/{{ .outputs.create-project.project_id }}"