
# Workerek

A workerek hosszú ideig futó folyamatok, amelyek függő feladatokért kérdezik le az adatbázist, végrehajtják őket, és továbbviszik a munkafolyamatokat. A `wp queuety work` parancs a WP-CLI környezetében fut, miközben a sorból közvetlenül a MySQL segítségével, a legjobb elérhető Queuety DB-illesztőprogramon keresztül veszi fel a feladatokat.

A bővítmény egy alapértelmezett, percenként egyszer futó WordPress cron tartalékmegoldást is telepít olyan környezetekhez, ahol nincs shell-hozzáférés. Ez az oldal a különálló WP-CLI workereket ismerteti, amelyek az ajánlott, nagyobb áteresztőképességű telepítési módot jelentik.

## Worker indítása

```bash
wp queuety work
```

Ez egyetlen workert indít a `default` soron. Ciklusban fut: felvesz egy feladatot, végrehajtja, majd ismétli a folyamatot. Ha a sor üres, `QUEUETY_WORKER_SLEEP` másodpercig vár (alapértelmezés: 1), mielőtt újra lekérdezi.

### Beállítások

| Beállítás | Leírás |
|---|---|
| `--queue=<queue>` | A feldolgozandó Queue(s), prioritási sorrendben, vesszővel elválasztva (alapértelmezés: `default`) |
| `--once` | Legfeljebb egy feladat feldolgozása, majd kilépés |
| `--workers=<n>` | N workerfolyamat indítása (a `pcntl` és `posix` bővítmények szükségesek) |
| `--min-workers=<n>` | Adaptív készlet minimális workerszáma. Szükséges hozzá a `--max-workers` |
| `--max-workers=<n>` | Adaptív készlet maximális workerszáma |

```bash
# Process a specific queue
wp queuety work --queue=emails

# Process at most one job and exit
wp queuety work --once

# Run 4 concurrent workers
wp queuety work --workers=4

# Scale between 2 and 6 workers as backlog changes
wp queuety work --queue=providers --min-workers=2 --max-workers=6
```

## Több sor prioritásai

Egyetlen worker több sort is feldolgozhat prioritási sorrendben. Adj át egy vesszővel elválasztott sornevekből álló listát a `--queue` számára:

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

A worker a felsorolt sorrendben próbál feladatot felvenni az egyes sorokból. Először a `critical` sort ellenőrzi. Ha a `critical` tartalmaz feladatot, feldolgozza. Ha a `critical` üres, továbblép a `default` sorra, majd a `low` sorra. Ez azt jelenti, hogy a magasabb prioritású sorok mindig kiürülnek az alacsonyabb prioritásúak előtt.

### Hogyan működik a prioritási sorrend

Minden ciklusban a worker megpróbál feladatot felvenni a lista első sorából. Ha az a sor üres vagy szüneteltetve van, továbblép a következőre, és így halad tovább, amíg fel nem talál egy feladatot, vagy el nem fogy a lista. Ha sehol sem talál feladatot, vár, majd újra próbálkozik. Ez szigorú prioritási modell: a `critical` feladatok folyamatos áradata kiéhezteti a `default` és `low` sorokat. Ha az alacsonyabb prioritású soroknak garantált áteresztőképességre van szükségük, használj külön workereket.

### Több sor használata a PHP környezetében

A `Worker::run()` és a `Worker::flush()` metódus karakterláncot vagy tömböt is elfogad:

```php
// Comma-separated string
Queuety::worker()->run( 'critical,default,low' );

// Array
Queuety::worker()->run( [ 'critical', 'default', 'low' ] );

// flush() also supports multi-queue
$count = Queuety::worker()->flush( 'critical,default,low' );
```

### Telepítési stratégiák

**A külön worker minden sorhoz** teljes irányítást biztosít a párhuzamosság és az elkülönítés felett. Minden sornak saját workerje van process(es), így a többi sor nem éheztetheti ki:

```ini
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=4

[program:queuety-default]
command=wp queuety work --queue=default
numprocs=2

[program:queuety-low]
command=wp queuety work --queue=low
numprocs=1
```

**Az egyetlen workerrel megvalósított prioritási sorrend** egyszerűbben kezelhető, és jól működik, ha az alacsonyabb prioritású sorok elviselik a késleltetést:

```ini
[program:queuety-worker]
command=wp queuety work --queue=critical,default,low
numprocs=2
```

A két megközelítést kombinálhatod is: használj külön workereket a `critical` számára az áteresztőképesség garantálásához, a többi feladathoz pedig prioritási sorrendű workert:

```ini
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=2

[program:queuety-fallback]
command=wp queuety work --queue=default,low
numprocs=2
```

## Erőforrás-tudatos felvétel

A workerek többet tesznek annál, mint hogy felveszik a következő függő sort. Mielőtt egy felvett feladat elindulna, a Queuety durva felvételi ellenőrzéseket végezhet a feladat párhuzamossági csoportja és az adott kezelő közelmúltbeli végrehajtási profilja alapján.

A tágabb modellről – többek között arról, hogyan kapcsolódik a feladatok metaadataihoz és a munkafolyamatok kereteihez – lásd az [Erőforrás-kezelés](https://queuety.inline0.dev/hu/docs/features/resource-management) oldalt.

A párhuzamossági csoport több kezelő vagy feladatosztály számára határoz meg közös felső korlátot. Ha több nagy erőforrásigényű szolgáltatónak ugyanazt a csoportot és korlátot állítod be, a worker felszabadítja az újonnan felvett feladatot, ahelyett hogy elindítaná, ha a csoport elérte a korlátját. Így a különálló sorok nem rohanják meg egyszerre ugyanazt a háttérrendszert csupán azért, mert több worker is tétlen.

A közelmúlt végrehajtási naplói egy egyszerű felvételi profilhoz is adatot szolgáltatnak. Ha az erőforrás-alapú felvétel engedélyezve van, a Queuety megvizsgálja a futtatandó kezelő közelmúltbeli átlagos időtartamát és csúcsmemória-használatát. Ha a worker már közel van a beállított memóriakorláthoz, egy sor vagy szolgáltatói csoport elérte súlyozott keretét, a jelenlegi konténerben a kezelő megfigyelt profilja alapján nem maradt elég memória, vagy egy `--once` jellegű futtatás közel van az időkerete végéhez, a Queuety elhalasztja a feladatot ahelyett, hogy olyan munkát indítana, amely valószínűleg nem fejeződik be hibamentesen.

A szabályzatot a munka definíciójánál kell bekapcsolni, nem a worker parancsánál:

```php
class CallProviderStep implements \Queuety\Step {
    public function handle( array $state ): array {
        // ...
    }

    public function config(): array {
        return [
            'concurrency_group' => 'providers',
            'concurrency_limit' => 3,
            'cost_units' => 5,
        ];
    }
}
```

Ugyanezek a metaadatok nyilvános tulajdonságokkal rendelkező, kiosztható feladatosztályokhoz vagy egyetlen kiosztáshoz is hozzárendelhetők a `PendingJob::concurrency_group()` és a `PendingJob::cost_units()` segítségével.

A workeroldali felvételi profilt a következő konstansok szabályozzák:

| Konstans | Leírás |
|---|---|
| `QUEUETY_RESOURCE_ADMISSION` | Profilalapú felvételi ellenőrzések engedélyezése vagy letiltása |
| `QUEUETY_RESOURCE_PROFILE_WINDOW_MINUTES` | Visszatekintési időszak a kezelők közelmúltbeli profiljainak összeállításához |
| `QUEUETY_RESOURCE_PROFILE_TTL` | A közelmúltbeli kezelőprofilok gyorsítótárának élettartama |
| `QUEUETY_RESOURCE_MEMORY_HEADROOM_MB` | Fenntartott memóriatartalék egy újabb feladat felvétele előtt |
| `QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS` | A konténer- vagy gazdagép-memória legjobb tudás szerinti ellenőrzésének engedélyezése vagy letiltása |
| `QUEUETY_RESOURCE_SYSTEM_MEMORY_HEADROOM_MB` | Fenntartott rendszermemória-tartalék egy újabb feladat felvétele előtt |
| `QUEUETY_RESOURCE_QUEUE_COST_BUDGETS` | Sornevek alapján megadott súlyozott költségkeretek |
| `QUEUETY_RESOURCE_GROUP_COST_BUDGETS` | `concurrency_group` alapján megadott súlyozott költségkeretek |
| `QUEUETY_RESOURCE_TIME_HEADROOM_MS` | Fenntartott időtartalék egyszeri workerfuttatásokhoz |

## A worker életciklusa

A worker az aktuális feladat befejezése után szabályosan leáll, ha az alábbi feltételek bármelyike teljesül:

| Feltétel | Beállítás |
|---|---|
| Feldolgozott feladatok maximális száma | `QUEUETY_WORKER_MAX_JOBS` (alapértelmezés: 1000) |
| Maximális memória túllépése | `QUEUETY_WORKER_MAX_MEMORY` (alapértelmezés: 128 MB) |

Leállás után a worker szabályosan kilép. Éles környezetben egy folyamatkezelő automatikusan újraindítja.

A jelek kezelése egyelőre nem szabályos ([#4](https://github.com/inline0/queuety/issues/4)). Egyetlen `wp queuety work` folyamat nem telepít jelkezelőt, ezért a `SIGTERM` vagy a `SIGINT` (Ctrl+C) azonnal leállítja, akár egy feladat közepén is. A feladat `processing` állapotban marad, amíg az elavultfeladat-helyreállítás `QUEUETY_STALE_TIMEOUT` másodperc után vissza nem állítja, ezért a kezelőknek biztonságosan újrapróbálhatóknak kell lenniük. A worker-készlet továbbítja a `SIGTERM` jelet a gyermekfolyamatainak, de azok nem reagálnak rá, így a készlet addig fut, amíg a fenti okok valamelyike miatt le nem állnak. Ha le kell állítanod egy készletet, állíts be időtúllépést a folyamatkezelőben, amely után az elküldi a `SIGKILL` jelet.

## Több worker párhuzamos futtatása

A `--workers=N` jelző N gyermekfolyamatot indít a `pcntl_fork()` segítségével. Minden gyermekfolyamat saját adatbázis-kapcsolatot hoz létre, és önállóan dolgozza fel a feladatokat. A szülőfolyamat figyeli a gyermekfolyamatokat, és újraindítja az összeomlókat.

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

Követelmények:
Telepíteni kell a `pcntl` és a `posix` PHP bővítményeket (`pcntl` nélkül a parancs hibát jelez: „pcntl extension is required for --workers=N.”), és minden gyermekfolyamat saját adatbázis-kapcsolatot használ, ezért a MySQL `max_connections` beállításnak elegendőnek kell lennie a készlet számára. Az adaptív készletekre (`--min-workers`/`--max-workers`) ugyanezek a követelmények vonatkoznak.

## Adaptív workerkészletek

Az adaptív készletek minimális számú workert tartanak készenlétben, majd a beállított tartományon belül növelik vagy csökkentik a számukat:

```bash
wp queuety work --queue=providers --min-workers=2 --max-workers=6
```

A szülőfolyamat figyeli a felvehető feladatok sorát a kiválasztott sorokban, és a gyermekfolyamatok számát ehhez igazítja, a beállított maximummal korlátozva. Amikor a sor forgalma lecsökken, a készlet kivárja a tétlenségi türelmi idő végét, mielőtt visszaskálázna, így a rövid kiugrások nem változtatják meg azonnal a folyamatlistát.

A felskálázás továbbra is óvatos. Ha a Queuety le tudja kérni a konténer vagy a gazdagép memóriaadatait, nem ad hozzá újabb gyermekfolyamatot, ha nincs elegendő szabad memória egy teljes worker futtatásához.

A szülőfolyamat skálázási ciklusát a következő beállítások szabályozzák:

| Konstans | Leírás |
|---|---|
| `QUEUETY_WORKER_POOL_SCALE_INTERVAL` | Milyen gyakran igazítja a szülőfolyamat a készlet méretét |
| `QUEUETY_WORKER_POOL_IDLE_GRACE` | Mennyi ideig kell csendesnek maradnia a sornak, mielőtt csökkenteni kezdi a méretet |

## Elakadt feladatok helyreállítása

Ha egy worker feladatfeldolgozás közben összeomlik, a feladat `processing` állapotban marad. Egy hosszan futó worker körülbelül percenként ellenőrzi, hogy vannak-e olyan feladatok, amelyek több mint `QUEUETY_STALE_TIMEOUT` másodperce vannak `processing` állapotban. A hátralévő próbálkozással rendelkező elakadt feladat az újrapróbálkozási késleltetés után újraindul; amelyik minden próbálkozását felhasználta, a sikertelenek közé kerül, a munkafolyamatát pedig sikertelennek jelöli. A `--once` workerek és a WP-Cron tartalékmegoldás nem végzik el ezt az ellenőrzést.

Az elakadt feladatok kézi helyreállítása:

```bash
wp queuety recover
```

## Kiürítési mód

Az összes függő feladat feldolgozása, majd kilépés. Teszteléshez vagy egyszeri kötegelt feldolgozáshoz hasznos:

```bash
wp queuety flush
wp queuety flush --queue=emails
```

## Telepítés éles környezetbe

Éles környezetben folyamatkezelővel gondoskodj a workerek folyamatos futtatásáról. Íme két gyakori megközelítés.

### Supervisord

```ini
[program:queuety-default]
command=wp queuety work --queue=default
directory=/var/www/html
autostart=true
autorestart=true
numprocs=2
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/var/log/queuety-default.log
stderr_logfile=/var/log/queuety-default-error.log

[program:queuety-emails]
command=wp queuety work --queue=emails
directory=/var/www/html
autostart=true
autorestart=true
numprocs=1
stdout_logfile=/var/log/queuety-emails.log
stderr_logfile=/var/log/queuety-emails-error.log
```

### Systemd

```ini
[Unit]
Description=Queuety Worker (default queue)
After=mysql.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html
ExecStart=/usr/local/bin/wp queuety work --queue=default
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

Engedélyezés és indítás:

```bash
sudo systemctl enable queuety-worker
sudo systemctl start queuety-worker
```

### Telepítési tippek

Erősebb elkülönítéshez futtass külön workereket az egyes sorokhoz. CPU-intenzív munkaterhelésnél használd a `--workers=N` beállítást, főként I/O-intenzív terhelésnél pedig részesítsd előnyben az egyenként felügyelt workereket. Állítsd be a `QUEUETY_WORKER_MAX_JOBS` értékét, ha időszakos újraindításokkal szabadítanál fel memóriát, és kövesd nyomon a `buried` számát a [webhookokon](https://queuety.inline0.dev/hu/docs/features/webhooks) vagy a [mérőszámokon](https://queuety.inline0.dev/hu/docs/features/metrics) keresztül.
