
# Arbetare

Arbetare är långlivade processer som söker efter väntande jobb i databasen, kör dem och för arbetsflödena vidare. Kommandot `wp queuety work` körs inuti WP-CLI, medan kön hämtas direkt från MySQL via den bästa tillgängliga DB-drivrutinen Queuety.

Pluginet installerar också en reservlösning med WordPress cron som körs en gång i minuten för miljöer utan shellåtkomst. Den här sidan handlar om dedikerade arbetare WP-CLI, det rekommenderade driftsättningsläget för högre genomströmning.

## Starta en arbetare

```bash
wp queuety work
```

Detta startar en enda arbetare på kön `default`. Den körs i en loop: hämta ett jobb, kör det, upprepa. När kön är tom väntar den i `QUEUETY_WORKER_SLEEP` sekunder (standard: 1) innan den söker igen.

### Alternativ

| Alternativ | Beskrivning |
|---|---|
| `--queue=<queue>` | Queue(s) som ska behandlas, kommaseparerade för prioritetsordning (standard: `default`) |
| `--once` | Behandla högst ett jobb och avsluta |
| `--workers=<n>` | Skapa N arbetarprocesser (kräver tilläggen `pcntl` och `posix`) |
| `--min-workers=<n>` | Minsta antal arbetare i en adaptiv pool. Kräver `--max-workers` |
| `--max-workers=<n>` | Högsta antal arbetare i en adaptiv pool |

```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
```

## Prioritering av flera köer

En arbetare kan behandla flera köer i prioritetsordning. Skicka en kommaseparerad lista med könamn till `--queue`:

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

Arbetaren försöker hämta ett jobb från varje kö i den angivna ordningen. Den kontrollerar `critical` först. Om `critical` har ett jobb behandlar den det jobbet. Om `critical` är tom går den vidare till `default` och sedan till `low`. Det innebär att köer med högre prioritet alltid töms före köer med lägre prioritet.

### Så fungerar prioritetsordningen

Vid varje iteration försöker arbetaren hämta ett jobb från den första kön i listan. Om kön är tom eller pausad går den vidare till nästa kö och fortsätter tills den hittar ett jobb eller har gått igenom hela listan. Om inget jobb hittas väntar arbetaren och försöker igen. Detta är en strikt prioritetsmodell, vilket innebär att en stadig ström av jobb i `critical` svälter ut `default` och `low`. Använd dedikerade arbetare om köer med lägre prioritet behöver garanterad genomströmning.

### Använda flera köer i PHP

Metoderna `Worker::run()` och `Worker::flush()` godtar antingen en sträng eller en array:

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

### Driftsättningsstrategier

**Dedikerade arbetare per kö** ger dig full kontroll över samtidighet och isolering. Varje kö får sin egen arbetarprocess(es) och kan inte svältas ut av andra köer:

```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
```

**Prioritetsordning med en enda arbetare** är enklare att hantera och fungerar bra när köer med lägre prioritet kan tåla förseningar:

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

Du kan också kombinera båda metoderna: dedikerade arbetare för `critical` för att garantera genomströmning och en arbetare med prioritetsordning för allt annat:

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

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

## Resursmedveten mottagning

Arbetare gör mer än att bara hämta nästa väntande rad. Innan ett hämtat jobb startar kan Queuety utföra grova mottagningskontroller baserade på jobbets samtidighetsgrupp och den senaste körningsprofilen för hanteraren.

Mer om den övergripande modellen och hur den hänger ihop med jobbmetadata och arbetsflödesbudgetar finns i [Resurshantering](https://queuety.inline0.dev/sv/docs/features/resource-management).

En samtidighetsgrupp ger flera hanterare eller jobbklasser ett gemensamt tak. Om du anger samma grupp och gräns för flera resurskrävande leverantörer frigör arbetaren nyligen hämtade jobb i stället för att starta dem när gruppen är fullbelastad. Då stormar oberoende köer inte samma nedströmsystem bara för att flera arbetare är lediga.

De senaste körningsloggarna bidrar också till en enkel mottagningsprofil. När resursbaserad mottagning är aktiverad granskar Queuety den senaste genomsnittliga körningstiden och toppminnesanvändningen för hanteraren som den ska köra. Om den aktuella arbetaren redan närmar sig sin konfigurerade minnesgräns, en kö eller leverantörsgrupp redan ligger vid sin viktade budget, den aktuella containern inte verkar ha tillräckligt med tillgängligt minne för hanterarens observerade profil eller en körning av typen `--once` närmar sig sin tidsgräns, skjuter Queuety upp jobbet i stället för att starta arbete som sannolikt inte kan slutföras ordentligt.

Du aktiverar policyn i arbetsdefinitionen, inte i arbetarens kommando:

```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,
        ];
    }
}
```

Samma metadata kan kopplas till jobbklasser som kan skickas och har publika egenskaper, eller till en enskild utskickning via `PendingJob::concurrency_group()` och `PendingJob::cost_units()`.

Mottagningsprofilen på arbetarens sida styrs av dessa konstanter:

| Konstant | Beskrivning |
|---|---|
| `QUEUETY_RESOURCE_ADMISSION` | Aktivera eller inaktivera profilbaserade mottagningskontroller |
| `QUEUETY_RESOURCE_PROFILE_WINDOW_MINUTES` | Hur långt tillbaka profiler för hanterare ska byggas från |
| `QUEUETY_RESOURCE_PROFILE_TTL` | Cache-TTL för aktuella profiler för hanterare |
| `QUEUETY_RESOURCE_MEMORY_HEADROOM_MB` | Reserverat minnesutrymme innan ytterligare ett jobb tas emot |
| `QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS` | Aktivera eller inaktivera bästa möjliga kontroller av container- eller värdminne |
| `QUEUETY_RESOURCE_SYSTEM_MEMORY_HEADROOM_MB` | Reserverat systemminne innan ytterligare ett jobb tas emot |
| `QUEUETY_RESOURCE_QUEUE_COST_BUDGETS` | Viktade kostnadsbudgetar sorterade efter könamn |
| `QUEUETY_RESOURCE_GROUP_COST_BUDGETS` | Viktade kostnadsbudgetar sorterade efter `concurrency_group` |
| `QUEUETY_RESOURCE_TIME_HEADROOM_MS` | Reserverad tidsmarginal för engångskörningar av arbetare |

## Arbetarens livscykel

En arbetare stoppas på ett ordnat sätt efter att ha slutfört sitt aktuella jobb när något av följande villkor uppfylls:

| Villkor | Konfiguration |
|---|---|
| Högsta antal behandlade jobb | `QUEUETY_WORKER_MAX_JOBS` (standard: 1000) |
| Minnesgränsen överskrids | `QUEUETY_WORKER_MAX_MEMORY` (standard: 128 MB) |

Efter stoppet avslutas arbetaren ordentligt. I produktion startar en processhanterare om den automatiskt.

Signaler hanteras ännu inte på ett ordnat sätt ([#4](https://github.com/inline0/queuety/issues/4)). En enskild `wp queuety work`-process installerar ingen signalhanterare, så `SIGTERM` eller `SIGINT` (Ctrl+C) avslutar den omedelbart, även mitt i ett jobb. Jobbet förblir `processing` tills återställning av föråldrade jobb återställer det efter `QUEUETY_STALE_TIMEOUT` sekunder, så se till att hanterare kan köras igen utan problem. En arbetarpool vidarebefordrar `SIGTERM` till sina underprocesser, men underprocesserna agerar inte på den, så poolen fortsätter att köras tills de stoppas av någon av orsakerna ovan. När du behöver stoppa en pool anger du en stopptidsgräns för processhanteraren, varefter den skickar `SIGKILL`.

## Samtidighet med flera arbetare

Flaggan `--workers=N` skapar N underprocesser med `pcntl_fork()`. Varje underprocess skapar en egen databasanslutning och behandlar jobb oberoende. Den överordnade processen övervakar underprocesserna och startar om dem som kraschar.

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

Krav:
Tilläggen `pcntl` och `posix` PHP måste vara installerade (utan `pcntl` misslyckas kommandot med ”pcntl extension is required for --workers=N.”), och varje underprocess använder en egen databasanslutning, så inställningen MySQL `max_connections` måste rymma hela poolen. Adaptiva pooler (`--min-workers`/`--max-workers`) har samma krav.

## Adaptiva arbetarpooler

Adaptiva pooler håller ett minsta antal arbetare redo och växer eller krymper sedan inom ett konfigurerat intervall:

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

Den överordnade processen övervakar den hämtningsbara kön i den valda könuppsättningen och justerar antalet underprocesser mot den kön, upp till den konfigurerade maxgränsen. När kön blir lugn väntar poolen under en inaktivitetsperiod innan den minskar igen, så korta toppar inte omedelbart ändrar processlistan.

Uppskalningen är fortfarande försiktig. När Queuety kan läsa minnesdata från containern eller värden lägger den inte till fler underprocesser om det återstående minnet inte räcker till för ytterligare en hel arbetarinstans.

Överordnad process skalas med följande inställningar:

| Konstant | Beskrivning |
|---|---|
| `QUEUETY_WORKER_POOL_SCALE_INTERVAL` | Hur ofta den överordnade processen stämmer av poolstorleken |
| `QUEUETY_WORKER_POOL_IDLE_GRACE` | Hur länge kön måste vara lugn innan poolen skalas ned |

## Återställning av föråldrade jobb

Om en arbetare kraschar medan den behandlar ett jobb lämnas jobbet med statusen `processing`. En långlivad arbetare kontrollerar ungefär en gång i minuten om jobb har varit i `processing` längre än `QUEUETY_STALE_TIMEOUT` sekunder. Ett föråldrat jobb med försök kvar körs igen efter sin fördröjning; ett jobb som har använt alla sina försök begravs och arbetsflödet markeras som misslyckat. Arbetare `--once` och reservalternativet WP-Cron utför inte den här kontrollen.

Återställ föråldrade jobb manuellt:

```bash
wp queuety recover
```

## Tömningsläge

Behandla alla väntande jobb och avsluta. Praktiskt för testning eller engångsvis batchbearbetning:

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

## Driftsättning i produktion

Använd en processhanterare i produktion för att hålla arbetare igång. Här är två vanliga tillvägagångssätt.

### 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
```

Aktivera och starta:

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

### Driftsättningstips

Kör separata arbetare för separata köer när du behöver bättre isolering. Använd `--workers=N` när arbetsbelastningen är CPU-bunden och föredra separat övervakade arbetare när den mest består av I/O. Ange `QUEUETY_WORKER_MAX_JOBS` om du vill starta om regelbundet för att frigöra minne, och håll koll på antalet `buried` via [webbhooks](https://queuety.inline0.dev/sv/docs/features/webhooks) eller [mätvärden](https://queuety.inline0.dev/sv/docs/features/metrics).
