agentsclimarketplace

Acorn queues

Skill hekivo/superpowers-sage/skills/acorn-queues

Background job processing in WordPress via Acorn: Laravel queue, dispatch, queue:work, ShouldQueue, failed jobs, Action Scheduler, as_schedule_single_action, as_schedule_recurring_action, job retries, backoff, job chaining, job batching, ShouldBeUnique, Acorn queue, Redis queue driver, database queue driver, queue worker, background tasks — using Acorn's Laravel queue stack in Sage/WordPressFrom its SKILL.md

Install
npx -y skills add hekivo/superpowers-sage --skill acorn-queues

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.0 KB, as published. Nobody here has run it

Queues, Jobs, and Background Tasks

When to Use What

CriteriaAction SchedulerLaravel Queue + Job
Best forSimple recurring tasks, WP-native workflowsRobust async, retry logic, heavy computation
InfrastructureNone — runs on WP cronNeeds queue driver (database or Redis)
Retry/backoffManualBuilt-in ($tries, $backoff, exponential)
MonitoringWP Admin > Tools > Scheduled Actionslando acorn queue:failed, logs
ExamplesDaily cleanups, content sync, email digestsImage processing, API syncs, bulk imports
Already availableBundled with WooCommerce; standalone via woocommerce/action-schedulerRequires Acorn queue config + worker

Rule of thumb: Start with Action Scheduler for simple recurring WordPress tasks. Move to Laravel Queue + Job when you need retries, backoff, chaining, batching, or processing that could take more than a few seconds.

Quick Start — Laravel Queue

# 1. Create a job class
bash skills/acorn-queues/scripts/create-job.sh ProcessImage

# 2. Create queue tables (database driver)
lando acorn queue:table
lando acorn queue:failed-table
lando acorn migrate

# 3. Set driver in .env
# QUEUE_CONNECTION=database

# 4. Start a worker
bash skills/acorn-queues/scripts/run-worker.sh
bash skills/acorn-queues/scripts/run-worker.sh emails

Quick Start — Action Scheduler

# Install (if not using WooCommerce)
lando composer require woocommerce/action-scheduler
// Schedule once
as_schedule_single_action(strtotime('+10 minutes'), 'app/sync_content', ['post_id' => 42], 'content-sync');

// Schedule recurring (guard against duplicates)
if (! as_has_scheduled_action('app/cleanup_tokens', [], 'maintenance')) {
    as_schedule_recurring_action(time(), HOUR_IN_SECONDS, 'app/cleanup_tokens', [], 'maintenance');
}

Register callbacks in ThemeServiceProvider::boot():

add_action('app/sync_content', function (int $postId): void {
    $this->app->make(\App\Services\ContentSyncService::class)->syncPost($postId);
});

Job Class Anatomy

class ProcessImage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public array $backoff = [10, 60, 300]; // exponential: 10s, 1min, 5min

    public function __construct(protected readonly int $attachmentId) {}

    public function handle(): void
    {
        // If job needs WP user context:
        // wp_set_current_user($this->userId);

        $file = get_attached_file($this->attachmentId);
        if (! $file || ! file_exists($file)) {
            return; // idempotent exit — attachment gone
        }
        // ... process
    }

    public function failed(?\Throwable $exception): void
    {
        Log::error('ProcessImage permanently failed', ['attachment_id' => $this->attachmentId]);
    }
}

Dispatching Jobs

// Basic
ProcessImage::dispatch(attachmentId: $id);

// Delayed (5 minutes)
SyncContent::dispatch(sourceId: $id)->delay(now()->addMinutes(5));

// Specific queue
SendEmail::dispatch(campaignId: $id)->onQueue('emails');

// From a WordPress hook
add_action('add_attachment', function (int $id): void {
    if (wp_attachment_is_image($id)) {
        ProcessImage::dispatch(attachmentId: $id);
    }
});

Scripts

# Create a job class (validates PascalCase, checks lando on PATH)
bash skills/acorn-queues/scripts/create-job.sh <JobName>

# Run a queue worker (default queue, 3 tries, 60s backoff)
bash skills/acorn-queues/scripts/run-worker.sh
bash skills/acorn-queues/scripts/run-worker.sh emails

Script source: scripts/create-job.sh · scripts/run-worker.sh

Assets

Boilerplate templates with {{CLASS_NAME}} placeholder. Copy and replace.

  • job-simple.php.tpl — Simple job with handle() + failed(), $tries, $backoff, wp_set_current_user stub.
  • job-batched.php.tpl — Batched job with use Batchable, $this->batch()->cancelled() check.

References

Deep content loaded on demand — zero tokens until needed.

  • action-scheduler.md — Action Scheduler setup, as_schedule_single_action, as_schedule_recurring_action, callbacks, duplicate-schedule prevention, cron-based queue trigger.
  • laravel-queue.md — Full config/queue.php, all drivers, database setup, dispatching patterns, job chaining, batching, testing with Bus::fake().
  • redis-driver.md — Redis-backed queue, Lando Redis service config (REDIS_HOST=cache), queue isolation, failover to database driver, Supervisor config.
  • job-patterns.md — Idempotency patterns, chunking large datasets, retry/backoff config, ShouldBeUnique + uniqueId(), wp_set_current_user in jobs, pass IDs not objects.
  • troubleshooting.md — Failed jobs table, queue:work debug flags, common errors (jobs stuck, Redis refused, class not found, memory exhaustion), escalation paths.

Verification

  • Dispatch a test job and confirm it appears in the queue: check the jobs table (database driver) or lando redis-cli -h cache LLEN queues:default (Redis driver).
  • Run lando acorn queue:work --once and confirm the job processes successfully with expected log output.
  • After processing, verify the job is removed from the queue and does not appear in lando acorn queue:failed.

Failure modes

Problem: Jobs dispatched but never processed

  • Cause: No worker is running, or QUEUE_CONNECTION in .env does not match a connection in config/queue.php.
  • Fix: Start a worker (bash skills/acorn-queues/scripts/run-worker.sh). Verify QUEUE_CONNECTION matches a valid connection key. For the database driver, run lando acorn queue:table && lando acorn migrate.

Problem: Jobs fail and the failed_jobs table does not exist

  • Cause: The failed jobs migration was never run.
  • Fix: lando acorn queue:failed-table && lando acorn migrate. Then retry with lando acorn queue:retry all.

For all other failure modes see references/troubleshooting.md.

Critical Rules

  1. Action Scheduler vs Laravel Queue: Use Action Scheduler for simple recurring WP-native tasks. Use Laravel Queue + Job when you need retries, backoff, chaining, batching, or heavy computation.
  2. wp_set_current_user in jobs: If a job calls current_user_can() or any WP function that relies on the current user, call wp_set_current_user($userId) at the top of handle(). Jobs run outside the HTTP lifecycle — WP does not set a current user automatically.
  3. Idempotency: Every job must be safe to run more than once. Use guard clauses or upsert patterns. See references/job-patterns.md.
  4. Pass IDs, not objects: Pass $postId instead of $post. Re-fetch in handle() to avoid serialization issues and stale data on retry.
  5. Set $tries and $backoff: Never let jobs retry infinitely. Use exponential backoff arrays for external API jobs.
  6. Failed jobs table must exist: Run lando acorn queue:failed-table && lando acorn migrate before running workers in production.
  7. sync driver is for development only. It blocks the HTTP request and runs jobs inline. Set QUEUE_CONNECTION=database or redis in production.
  8. Redis host inside Lando is the service name (cache), not 127.0.0.1. See references/redis-driver.md.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.