
# Primii pași

## Instalare

### Cerințe

- PHP 8.2 sau mai recent și WordPress 6.4 sau mai recent
- MySQL 8.0+ sau MariaDB 10.6+. Lucrătorii revendică joburi și programări scadente cu `SELECT ... FOR UPDATE SKIP LOCKED`, sintaxă pe care serverele mai vechi o resping cu o eroare.
- `mysqli` sau `pdo_mysql` (consultați mai jos)
- WP-CLI pe server dacă rulați lucrători dedicați cu `wp queuety work`
- Extensiile `pcntl` și `posix` PHP dacă rulați grupuri de lucrători cu `--workers` sau `--min-workers`/`--max-workers`

Queuety necesită fie `mysqli`, fie `pdo_mysql` în mediul de execuție PHP care încarcă WordPress și WP-CLI. Alege automat driverul, preferând `mysqli` pentru mediile de execuție WordPress și păstrând `pdo_mysql` disponibil pentru utilizarea autonomă/directă a mediului de execuție.

Dacă doriți mediul de execuție bazat pe DB fără stratul de pluginuri WordPress, consultați [Utilizare autonomă](https://queuety.inline0.dev/ro/docs/features/standalone-use). Această variantă folosește aceeași conexiune și aceleași tabele pentru mediul de execuție, însă nu include punțile hookurilor WordPress sau înregistrarea WP-CLI.

### Din arhiva zip a versiunii

Fiecare versiune [GitHub](https://github.com/inline0/queuety/releases) are un fișier `queuety.zip`: pluginul cu dependențele Composer deja instalate. Instalați ultima versiune cu WP-CLI:

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

Sau descărcați arhiva zip și încărcați-o din Plugins > Add New > Upload Plugin. Aceasta este cea mai simplă variantă pentru un site WordPress obișnuit.

### Prin Composer pentru Composer gestionat de WordPress

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

Apoi activați pluginul:

```bash
wp plugin activate queuety
```

Tipul pachetului este `wordpress-plugin`. Composer îl plasează în directorul de pluginuri doar când proiectul necesită `composer/installers` și mapează acel tip la o cale de instalare, așa cum face Bedrock, iar proiectul trebuie să-și încarce propriul `vendor/autoload.php` (și Bedrock face acest lucru). Fără `composer/installers`, Composer îl instalează în `vendor/queuety/queuety`, unde WordPress nu îl găsește, așa că folosiți arhiva zip a versiunii pe o instalare WordPress simplă.

### Din sursă în timpul dezvoltării

Plasați depozitul în `wp-content/plugins/queuety`, apoi instalați dependențele PHP:

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

La activare, Queuety își creează tabelele bazei de date (`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`), astfel încât lucrătorii să poată prelua sarcini direct din MySQL.

În mod implicit, pluginul programează și un lucrător cu o singură execuție prin WordPress cron în fiecare minut pentru coada `default`. Astfel aveți o soluție de bază fără shell pentru sarcini și fluxuri de lucru care rulează pe `default`, cu condiția ca WordPress cron să se declanșeze. Fiecare execuție procesează cel mult o sarcină și nu declanșează programări recurente, nu recuperează sarcini rămase blocate și nu verifică termenele fluxurilor de lucru; acestea rulează doar într-un proces `wp queuety work` de lungă durată ([#14](https://github.com/inline0/queuety/issues/14)). Pentru cozi personalizate, programări recurente, latență mai mică sau volume de lucru mai mari, treceți la procese `wp queuety work` dedicate.

## Configurare

Toate constantele sunt opționale. Definiți-le în `wp-config.php` înainte de încărcarea pluginului sau înainte ca Queuety să pornească într-o instalare încorporată în stilul unei teme:

| Constantă | Valoare implicită | Descriere |
|---|---|---|
| `QUEUETY_RETENTION_DAYS` | `7` | Vârsta implicită, în zile, pentru `wp queuety purge` și `Queuety::purge()`. Nimic nu este șters automat |
| `QUEUETY_LOG_RETENTION_DAYS` | `0` | Este citită de `Config::log_retention_days()`, dar încă nu este folosită; jurnalele sunt păstrate până când apelați `Queuety::purge_logs()` ([#15](https://github.com/inline0/queuety/issues/15)) |
| `QUEUETY_MAX_EXECUTION_TIME` | `300` | Numărul maxim de secunde per sarcină înainte de expirarea timpului (încă nu este aplicat, consultați [Sarcini](https://queuety.inline0.dev/ro/docs/jobs#timeout)) |
| `QUEUETY_WORKER_SLEEP` | `1` | Numărul de secunde de așteptare când coada este goală |
| `QUEUETY_WORKER_MAX_JOBS` | `1000` | Numărul maxim de sarcini înainte de repornirea lucrătorului |
| `QUEUETY_WORKER_MAX_MEMORY` | `128` | Numărul maxim de MB înainte de repornirea lucrătorului |
| `QUEUETY_RETRY_BACKOFF` | `exponential` | Strategia de așteptare progresivă: `exponential`, `linear` sau `fixed` |
| `QUEUETY_STALE_TIMEOUT` | `600` | Numărul de secunde înainte de recuperarea sarcinilor blocate |
| `QUEUETY_CACHE_TTL` | `5` | Durata implicită de păstrare a memoriei cache, în secunde |
| `QUEUETY_DEBUG` | `false` | Activează înregistrarea detaliată în jurnal a lucrătorului |
| `QUEUETY_CLI_COMMAND` | `queuety` | Numele comenzii rădăcină WP-CLI |
| `QUEUETY_TABLE_PREFIX` | `queuety_` | Nume de bază comun pentru toate tabelele Queuety după prefixul bazei de date WordPress |
| `QUEUETY_TABLE_JOBS` | `queuety_jobs` | Numele tabelului pentru sarcini |
| `QUEUETY_TABLE_WORKFLOWS` | `queuety_workflows` | Numele tabelului pentru fluxuri de lucru |
| `QUEUETY_TABLE_LOGS` | `queuety_logs` | Numele tabelului pentru jurnale |
| `QUEUETY_TABLE_SCHEDULES` | `queuety_schedules` | Numele tabelului pentru programări |
| `QUEUETY_TABLE_SIGNALS` | `queuety_signals` | Numele tabelului pentru semnale |
| `QUEUETY_TABLE_WORKFLOW_DEPENDENCIES` | `queuety_workflow_dependencies` | Numele tabelului pentru așteptările dependențelor fluxurilor de lucru |
| `QUEUETY_TABLE_WORKFLOW_DISPATCH_KEYS` | `queuety_workflow_dispatch_keys` | Numele tabelului pentru idempotența fluxurilor de lucru durabile |
| `QUEUETY_TABLE_CHUNKS` | `queuety_chunks` | Numele tabelului pentru segmentele transmise în flux |
| `QUEUETY_TABLE_QUEUE_STATES` | `queuety_queue_states` | Numele tabelului pentru stările cozilor |
| `QUEUETY_TABLE_WEBHOOKS` | `queuety_webhooks` | Numele tabelului pentru webhook-uri |
| `QUEUETY_TABLE_LOCKS` | `queuety_locks` | Numele tabelului pentru blocări |
| `QUEUETY_TABLE_BATCHES` | `queuety_batches` | Numele tabelului pentru loturi |
| `QUEUETY_TABLE_WORKFLOW_EVENTS` | `queuety_workflow_events` | Numele tabelului pentru jurnalul de evenimente al fluxului de lucru |
| `QUEUETY_TABLE_ARTIFACTS` | `queuety_artifacts` | Numele tabelului pentru artefactele fluxului de lucru |
| `QUEUETY_TABLE_STATE_MACHINES` | `queuety_state_machines` | Numele tabelului pentru mașinile de stări |
| `QUEUETY_TABLE_STATE_MACHINE_EVENTS` | `queuety_state_machine_events` | Numele tabelului pentru jurnalul de evenimente al mașinii de stări |
| `QUEUETY_DB_DRIVER` | `auto` | Driverul MySQL: `auto`, `mysqli` sau `pdo`. `auto` preferă `mysqli` când este încărcat WordPress; în caz contrar, `pdo_mysql`, apoi `mysqli` |

Constantele pentru admiterea resurselor și pentru pool-ul adaptiv (`QUEUETY_RESOURCE_*`, `QUEUETY_WORKER_POOL_*`) sunt enumerate pe pagina [Lucrători](https://queuety.inline0.dev/ro/docs/features/workers).

`QUEUETY_TABLE_PREFIX` modifică doar segmentul Queuety al numelor tabelelor. Prefixul bazei de date WordPress încapsulează în continuare rezultatul, astfel că `$wpdb->prefix = 'wp_'` și `QUEUETY_TABLE_PREFIX = 'themequeue_'` produc tabele precum `wp_themequeue_jobs`. Constantele explicite `QUEUETY_TABLE_*` au în continuare prioritate pentru tabele individuale.

Conexiunile independente pot seta și prefixul tabelului Queuety pentru fiecare conexiune:

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

Astfel, prefixul bazei de date WordPress rămâne intact, iar doar segmentul tabelului Queuety se modifică.

## Prima sarcină

Creați o clasă de gestionare care implementează interfața `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,
        ];
    }
}
```

Înregistrați-o și lansați sarcina:

```php
use Queuety\Queuety;

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

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

Sau folosiți clasa modernă de sarcină lansabilă:

```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!' );
```

## Primul flux de lucru

Definiți gestionare de pași care implementează interfața `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 [];
    }
}
```

Lansați fluxul de lucru:

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

## Porniți un lucrător

```bash
wp queuety work
```

Lucrătorul verifică dacă există sarcini în așteptare, le execută, avansează fluxurile de lucru și așteaptă când coada este goală. Apăsați `Ctrl+C` pentru a opri; procesul se încheie imediat, chiar și în mijlocul unei sarcini (consultați [Lucrători](https://queuety.inline0.dev/ro/docs/features/workers#worker-lifecycle)).

`SendEmailHandler` de mai sus își trimite sarcinile în coada `emails` prin `config()`, astfel încât un lucrător de pe `default` nu le preia. Specificați fiecare coadă pe care o folosiți:

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

Dacă nu rulați un lucrător dedicat, Queuety are în continuare soluția de rezervă implicită WordPress cron, descrisă mai sus, care rulează o dată pe minut și este limitată la coada `default` și la o singură sarcină per execuție. Lucrătorul dedicat oferă debit mai mare și latență mai mică.

Pentru producție, rulați mai mulți lucrători:

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

Procesați mai multe cozi cu ordonare după prioritate:

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

## Ce urmează

- [Sarcini](https://queuety.inline0.dev/ro/docs/jobs) pentru ghidul complet despre lansare și gestionare
- [Fluxuri de lucru](https://queuety.inline0.dev/ro/docs/workflows) pentru lanțuri, pași paraleli, ramificare condiționată și lansarea fluxurilor de lucru
- [Middleware](https://queuety.inline0.dev/ro/docs/features/middleware) pentru limitarea ratei, reducerea frecvenței și logica personalizată a pipeline-ului
- [Procesare în loturi](https://queuety.inline0.dev/ro/docs/features/batching) pentru lansarea grupurilor de sarcini cu funcții callback
- [Pași cu transmitere în flux](https://queuety.inline0.dev/ro/docs/workflows/streaming) pentru salvarea datelor transmise în flux, segment cu segment
- [Programare](https://queuety.inline0.dev/ro/docs/features/scheduling) pentru sarcini recurente
- [Memorare în cache](https://queuety.inline0.dev/ro/docs/features/caching) pentru stratul de cache modular
- [Testare](https://queuety.inline0.dev/ro/docs/features/testing) pentru QueueFake și aserțiunile de testare
- [CLI Referință](https://queuety.inline0.dev/ro/docs/cli) pentru toate comenzile disponibile
- [PHP API](https://queuety.inline0.dev/ro/docs/api) pentru acces programatic
