
# Primeros pasos

## Instalación

### Requisitos

- PHP 8.2 o posterior y WordPress 6.4 o posterior
- MySQL 8.0+ o MariaDB 10.6+. Los trabajadores reclaman trabajos y programaciones pendientes mediante `SELECT ... FOR UPDATE SKIP LOCKED`, que los servidores más antiguos rechazan con un error de sintaxis.
- `mysqli` o `pdo_mysql` (consulte más abajo)
- WP-CLI en el servidor si ejecuta trabajadores dedicados con `wp queuety work`
- Las extensiones `pcntl` y `posix` PHP si ejecuta grupos de trabajadores con `--workers` o `--min-workers`/`--max-workers`

Queuety requiere `mysqli` o `pdo_mysql` en el entorno de ejecución PHP que carga WordPress y WP-CLI. Selecciona el controlador automáticamente: prefiere `mysqli` en entornos de ejecución WordPress y mantiene `pdo_mysql` disponible para el uso directo o independiente del entorno.

Si quiere usar el entorno de ejecución respaldado por la base de datos sin la capa del plugin WordPress, consulte [Uso independiente](https://queuety.inline0.dev/es/docs/features/standalone-use). Esa opción usa la misma conexión y las mismas tablas del entorno de ejecución, pero no incluye los puentes de hooks de WordPress ni el registro de WP-CLI.

### Desde el archivo zip de la versión

Todas las [versiones de GitHub](https://github.com/inline0/queuety/releases) incluyen un archivo `queuety.zip`: el plugin con sus dependencias de Composer ya instaladas. Instale la versión más reciente con WP-CLI:

```bash
wp plugin install https://github.com/inline0/queuety/releases/latest/download/queuety.zip --activate
```

También puede descargar el archivo zip y subirlo desde Plugins > Añadir nuevo > Subir plugin. Es la forma más sencilla para un sitio WordPress convencional.

### Mediante Composer para Composer gestionado con WordPress

```bash
composer require queuety/queuety
```

A continuación, active el plugin:

```bash
wp plugin activate queuety
```

El tipo de paquete es `wordpress-plugin`. Composer lo coloca en el directorio de plugins solo cuando el proyecto requiere `composer/installers` y asigna ese tipo a una ruta de instalación, como hace Bedrock, y el proyecto debe cargar su propio `vendor/autoload.php` (Bedrock también lo hace). Sin `composer/installers`, Composer lo instala en `vendor/queuety/queuety`, donde WordPress no lo encuentra, así que use el archivo zip de la versión en una instalación normal de WordPress.

### Desde el código fuente durante el desarrollo

Coloque el repositorio en `wp-content/plugins/queuety` y luego instale las dependencias de PHP:

```bash
composer install
wp plugin activate queuety
```

Al activarse, Queuety crea sus tablas de base de datos (`queuety_jobs`, `queuety_workflows`, `queuety_logs`, `queuety_schedules`, `queuety_queue_states`, `queuety_webhooks`, `queuety_locks`, `queuety_signals`, `queuety_workflow_dependencies`, `queuety_workflow_dispatch_keys`, `queuety_batches`, `queuety_chunks`, `queuety_workflow_events`, `queuety_artifacts`, `queuety_state_machines`, `queuety_state_machine_events`) para que los workers puedan reclamar tareas directamente desde MySQL.

De forma predeterminada, el plugin también programa un worker de una sola ejecución mediante WordPress cron cada minuto para la cola `default`. Esto ofrece una configuración básica sin shell para tareas y flujos de trabajo que permanecen en `default`, siempre que se active WordPress cron. Cada ejecución procesa como máximo una tarea y no activa programaciones recurrentes, recupera tareas obsoletas ni comprueba los plazos de los flujos de trabajo; esas funciones solo se ejecutan dentro de un proceso `wp queuety work` de larga duración ([#14](https://github.com/inline0/queuety/issues/14)). Para colas personalizadas, programaciones recurrentes, menor latencia o cargas de trabajo más pesadas, use procesos `wp queuety work` dedicados.

## Configuración

Todas las constantes son opcionales. Defínalas en `wp-config.php` antes de que se cargue el plugin o antes de que Queuety se inicie en una instalación integrada al estilo de un tema:

| Constante | Valor predeterminado | Descripción |
|---|---|---|
| `QUEUETY_RETENTION_DAYS` | `7` | Antigüedad predeterminada, en días, para `wp queuety purge` y `Queuety::purge()`. No se purga nada automáticamente |
| `QUEUETY_LOG_RETENTION_DAYS` | `0` | `Config::log_retention_days()` la lee, pero aún no se usa; los registros se conservan hasta que se llame a `Queuety::purge_logs()` ([#15](https://github.com/inline0/queuety/issues/15)) |
| `QUEUETY_MAX_EXECUTION_TIME` | `300` | Segundos máximos por tarea antes del tiempo de espera agotado (aún no se aplica; consulte [Jobs](https://queuety.inline0.dev/es/docs/jobs#timeout)) |
| `QUEUETY_WORKER_SLEEP` | `1` | Segundos de espera cuando la cola está vacía |
| `QUEUETY_WORKER_MAX_JOBS` | `1000` | Número máximo de tareas antes de que se reinicie el worker |
| `QUEUETY_WORKER_MAX_MEMORY` | `128` | MB máximos antes de que se reinicie el worker |
| `QUEUETY_RETRY_BACKOFF` | `exponential` | Estrategia de espera: `exponential`, `linear` o `fixed` |
| `QUEUETY_STALE_TIMEOUT` | `600` | Segundos antes de recuperar tareas bloqueadas |
| `QUEUETY_CACHE_TTL` | `5` | TTL predeterminado de la caché, en segundos |
| `QUEUETY_DEBUG` | `false` | Activar el registro detallado del worker |
| `QUEUETY_CLI_COMMAND` | `queuety` | Nombre del comando raíz de WP-CLI |
| `QUEUETY_TABLE_PREFIX` | `queuety_` | Nombre base compartido de todas las tablas de Queuety después del prefijo de base de datos de WordPress |
| `QUEUETY_TABLE_JOBS` | `queuety_jobs` | Nombre de la tabla de tareas |
| `QUEUETY_TABLE_WORKFLOWS` | `queuety_workflows` | Nombre de la tabla de flujos de trabajo |
| `QUEUETY_TABLE_LOGS` | `queuety_logs` | Nombre de la tabla de registros |
| `QUEUETY_TABLE_SCHEDULES` | `queuety_schedules` | Nombre de la tabla de programaciones |
| `QUEUETY_TABLE_SIGNALS` | `queuety_signals` | Nombre de la tabla de señales |
| `QUEUETY_TABLE_WORKFLOW_DEPENDENCIES` | `queuety_workflow_dependencies` | Nombre de la tabla de esperas por dependencias de flujos de trabajo |
| `QUEUETY_TABLE_WORKFLOW_DISPATCH_KEYS` | `queuety_workflow_dispatch_keys` | Nombre de la tabla de idempotencia de flujos de trabajo duraderos |
| `QUEUETY_TABLE_CHUNKS` | `queuety_chunks` | Nombre de la tabla de fragmentos de transmisión |
| `QUEUETY_TABLE_QUEUE_STATES` | `queuety_queue_states` | Nombre de la tabla de estados de cola |
| `QUEUETY_TABLE_WEBHOOKS` | `queuety_webhooks` | Nombre de la tabla de webhooks |
| `QUEUETY_TABLE_LOCKS` | `queuety_locks` | Nombre de la tabla de bloqueos |
| `QUEUETY_TABLE_BATCHES` | `queuety_batches` | Nombre de la tabla de lotes |
| `QUEUETY_TABLE_WORKFLOW_EVENTS` | `queuety_workflow_events` | Nombre de la tabla del registro de eventos de flujos de trabajo |
| `QUEUETY_TABLE_ARTIFACTS` | `queuety_artifacts` | Nombre de la tabla de artefactos de flujos de trabajo |
| `QUEUETY_TABLE_STATE_MACHINES` | `queuety_state_machines` | Nombre de la tabla de máquinas de estados |
| `QUEUETY_TABLE_STATE_MACHINE_EVENTS` | `queuety_state_machine_events` | Nombre de la tabla del registro de eventos de máquinas de estados |
| `QUEUETY_DB_DRIVER` | `auto` | Controlador MySQL: `auto`, `mysqli` o `pdo`. `auto` prefiere `mysqli` cuando WordPress está cargado; de lo contrario, `pdo_mysql` y luego `mysqli` |

Las constantes de admisión de recursos y del pool adaptativo (`QUEUETY_RESOURCE_*`, `QUEUETY_WORKER_POOL_*`) se enumeran en la página [Workers](https://queuety.inline0.dev/es/docs/features/workers).

`QUEUETY_TABLE_PREFIX` cambia solo la parte Queuety de los nombres de las tablas. El prefijo de base de datos de WordPress sigue envolviendo el resultado, por lo que `$wpdb->prefix = 'wp_'` y `QUEUETY_TABLE_PREFIX = 'themequeue_'` generan tablas como `wp_themequeue_jobs`. Las constantes `QUEUETY_TABLE_*` explícitas siguen teniendo prioridad para cada tabla.

Las conexiones independientes también pueden establecer el prefijo de tabla Queuety por conexión:

```php
$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
    table_prefix: 'themequeue_',
);
```

Así se conserva intacto el prefijo de base de datos de WordPress y solo se cambia el segmento de tabla Queuety.

## Su primera tarea

Cree una clase controladora que implemente la interfaz `Handler`:

```php
use Queuety\Handler;

class SendEmailHandler implements Handler {
    public function handle( array $payload ): void {
        wp_mail( $payload['to'], $payload['subject'], $payload['body'] );
    }

    public function config(): array {
        return [
            'queue'           => 'emails',
            'max_attempts'    => 5,
        ];
    }
}
```

Regístrela y envíe la tarea:

```php
use Queuety\Queuety;

Queuety::register( 'send_email', SendEmailHandler::class );

Queuety::dispatch( 'send_email', [
    'to'      => 'user@example.com',
    'subject' => 'Welcome',
    'body'    => 'Hello from Queuety!',
] );
```

O use la clase moderna de tarea enviable:

```php
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

readonly class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

SendEmailJob::dispatch( 'user@example.com', 'Welcome', 'Hello from Queuety!' );
```

## Su primer flujo de trabajo

Defina controladores de pasos que implementen la interfaz `Step`:

```php
use Queuety\Step;

class FetchDataHandler implements Step {
    public function handle( array $state ): array {
        $user = get_user_by( 'ID', $state['user_id'] );
        return [ 'user_name' => $user->display_name ];
    }

    public function config(): array {
        return [];
    }
}

class CallLLMHandler implements Step {
    public function handle( array $state ): array {
        $response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', [
            'body' => json_encode( [ 'prompt' => "Generate report for {$state['user_name']}" ] ),
        ] );
        return [ 'llm_response' => wp_remote_retrieve_body( $response ) ];
    }

    public function config(): array {
        return [ 'max_attempts' => 5 ];
    }
}

class FormatOutputHandler implements Step {
    public function handle( array $state ): array {
        $url = save_report( $state['user_name'], $state['llm_response'] );
        return [ 'report_url' => $url ];
    }

    public function config(): array {
        return [];
    }
}
```

Envíe el flujo de trabajo:

```php
$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

## Inicie un worker

```bash
wp queuety work
```

El worker busca tareas pendientes, las ejecuta, avanza los flujos de trabajo y espera cuando la cola está vacía. Pulse `Ctrl+C` para detenerlo; esto finaliza el proceso de inmediato, incluso si está en mitad de una tarea (consulte [Workers](https://queuety.inline0.dev/es/docs/features/workers#worker-lifecycle)).

El `SendEmailHandler` anterior envía sus tareas a la cola `emails` mediante `config()`, por lo que un worker en `default` no las recoge. Asigne un nombre a cada cola que use:

```bash
wp queuety work --queue=emails,default
```

Si no ejecuta un worker dedicado, Queuety sigue contando con la alternativa predeterminada de WordPress cron, que se ejecuta una vez por minuto como se describió antes, limitada a la cola `default` y a una tarea por ejecución. El worker dedicado ofrece mayor rendimiento y menor latencia.

En producción, ejecute varios workers:

```bash
wp queuety work --workers=4
```

Procese varias colas según el orden de prioridad:

```bash
wp queuety work --queue=high,default,low
```

## Qué sigue

- [Jobs](https://queuety.inline0.dev/es/docs/jobs) para consultar la guía completa de envío y controladores
- [Workflows](https://queuety.inline0.dev/es/docs/workflows) para cadenas, pasos paralelos, ramificación condicional y ejecución de flujos de trabajo
- [Middleware](https://queuety.inline0.dev/es/docs/features/middleware) para limitar la frecuencia, regular el procesamiento y añadir lógica personalizada a la canalización
- [Batching](https://queuety.inline0.dev/es/docs/features/batching) para enviar grupos de tareas con funciones de retorno
- [Streaming Steps](https://queuety.inline0.dev/es/docs/workflows/streaming) para guardar datos transmitidos fragmento por fragmento
- [Scheduling](https://queuety.inline0.dev/es/docs/features/scheduling) para tareas recurrentes
- [Caching](https://queuety.inline0.dev/es/docs/features/caching) para la capa de caché conectable
- [Testing](https://queuety.inline0.dev/es/docs/features/testing) para QueueFake y las aserciones de pruebas
- [CLI Reference](https://queuety.inline0.dev/es/docs/cli) para todos los comandos disponibles
- [PHP API](https://queuety.inline0.dev/es/docs/api) para el acceso programático
