
# Erőforrás-kezelés

Queuety az erőforrás-szabályozást négy alapvető rétegre bontja, amelyeket opcionális poolméretezés egészít ki.

Az első réteg azt írja le, mennyibe kerül egy munkaegység. A második korlátozza, hogy egy várólista vagy szolgáltatói csoport mekkora közös terhelést viselhet egyszerre. A harmadik meghatározza, mennyit használhat fel egyetlen munkafolyamat-futás. A negyedik dönti el, hogy a worker azonnal elindítsa-e a következő átvett feladatot, vagy halassza el, amíg a jelenlegi folyamatban és konténerben elegendő tartalék nem marad.

Ezek a rétegek együttműködnek. Egy kezelő jelezheti, hogy nagy terhelésű közös poolhoz tartozik, a várólista korlátozhatja az adott szolgáltatóhoz lefoglalt súlyozott munkát, a munkafolyamat megszabhatja, mennyi ilyen munkát hozhat létre, a worker pedig továbbra is megtagadhatja a munka elindítását, ha a folyamat vagy a konténer már túl közel van a korlátaihoz.

## Egy munkaegység költségének leírása

A feladatok, a munkafolyamat-lépések és az állapotba lépéskor végrehajtott műveletek ugyanazt a három erőforrásra vonatkozó jelzést tehetik közzé:

- `concurrency_group`
- `concurrency_limit`
- `cost_units`

A `concurrency_group` és a `concurrency_limit` egy downstream rendszer közös terhelését írja le. Ha több kezelő is ugyanazt a szolgáltatót, API fiókot vagy bérlőt veszi igénybe, ugyanazt a csoportot használhatják, így a workerek nem indítanak el egyszerre túl sok feladatot.

A `cost_units` a relatív súlyt írja le. Egy gyorsítótár-frissítés és egy nagy szolgáltatói hívás egyaránt „egy feladat” lehet, de nem szabad egyformán beleszámítaniuk, amikor egy munkafolyamat kerete vagy a worker felvételi szabálya eldönti, hogy biztonságos-e további munkát indítani.

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

Ugyanez vonatkozik az osztálytulajdonságokon keresztül indítható feladatokra, valamint az egyedi dispatch-ekre a `PendingJob::concurrency_group()` és a `PendingJob::cost_units()` használatával.

## Megosztott várólisták és szolgáltatói csoportok kereteinek beállítása

A közös terhelés szabályozása nem mindig egyszerű párhuzamossági számot jelent. Néha a már futó feladatok együttes súlya a költséges.

A Queuety súlyozott várólista- és csoportkeretekkel biztosítja ezt. A várólistakeretek kulcsa a várólista neve. A csoportkeretek kulcsa a `concurrency_group`, így egymástól független kezelők is ugyanahhoz a közös kerethez tartozhatnak.

```php
define( 'QUEUETY_RESOURCE_QUEUE_COST_BUDGETS', [
    'providers' => 20,
    'exports' => 8,
] );

define( 'QUEUETY_RESOURCE_GROUP_COST_BUDGETS', [
    'openai' => 12,
    'tenant:acme' => 6,
] );
```

Amikor egy worker átvesz egy feladatot, megvizsgálja azokat az aktív `processing` sorokat, amelyek már az adott várólistához vagy csoporthoz tartoznak. Ha a jelenleg futó költség és az átvett feladat `cost_units` értékének összege meghaladná a beállított keretet, a worker visszaadja a feladatot, és később újra próbálkozik.

Ez más szabályozást tesz lehetővé, mint a `concurrency_limit`. Egy szolgáltató engedélyezhet három párhuzamos kérést, miközben a nagyobb kérésekre kevesebb összes költségegységet tart fenn, mint a kisebbekre.

## Egy munkafolyamat kereteinek betartása

A munkafolyamat-keretek olyan esetekre valók, amikor nem egyetlen nehéz feladat okoz gondot, hanem a futás a tervezettnél több munkát talál folyamatosan.

Ez gyakori az ügynökalapú rendszerekben. Egy tervező újra és újra előveheti ugyanazt a költséges ágat, túl sok részfeladatra bonthat egy feladatot, vagy folyamatosan elindíthat gyermek-munkafolyamatokat úgy, hogy közben a normál újrapróbálkozási modell keretein belül marad.

A Queuety munkafolyamat-szintű korlátokat biztosít erre az esetre:

```php
Queuety::workflow( 'research_run' )
    ->max_transitions( 20 )
    ->max_for_each_items( 12 )
    ->max_state_bytes( 32768 )
    ->max_cost_units( 40 )
    ->max_started_workflows( 8 )
    ->then( PlanResearchStep::class )
    ->for_each( 'tasks', ExecuteResearchTask::class, 'results' )
    ->dispatch();
```

A `max_cost_units()` megakadályozza, hogy a futás a tervezettnél több súlyozott munkát használjon fel. A `max_started_workflows()` meggátolja, hogy egy szülő korlátlan számú legfelső szintű gyermekfutásból álló fává nőjön. A többi védőkorlát továbbra is fontos, mert nem minden elszabaduló munkafolyamat egyformán költséges.

A munkafolyamat állapota a nyilvános `budget` adatban teszi elérhetővé a beállított korlátokat és a jelenlegi felhasználást, így a futás ezek érvényessége alatt is nyomon követhető marad.

## A munka elhalasztása, ha a folyamat már túlterhelt

Még megfelelő metaadatok és munkafolyamat-keretek esetén is a feladat végrehajtására készülő workerfolyamat hozza meg a végső döntést.

Itt lép működésbe az erőforrás-tudatos felvétel. Egy átvett feladat indítása előtt a Queuety megvizsgálhatja a következőket:

- a feladat megosztott párhuzamossági csoportja
- a súlyozott várólista- és szolgáltatóicsoport-keretek
- a kezelő korábbi futásideje és csúcsmemória-használata
- a jelenlegi worker megmaradt memóriakerete
- a jelenlegi konténer vagy gazdagép megmaradt memóriakerete
- az egyszeri futásokra rendelkezésre álló időkeret

Ha a worker már túl közel van a beállított felső határhoz, a Queuety visszaadja a feladatot, ahelyett, hogy olyan munkát indítana, amely valószínűleg nem fejeződik be problémamentesen.

Ez szándékosan óvatos megoldás. Nem teljes értékű fürtütemező. Olyan biztonsági réteg, amely segít a leterhelt workernek elkerülni a futtató folyamat túlterhelését, és memóriaadatok esetén a körülötte lévő konténer vagy gazdagép túlterhelését is.

A konténerre vagy gazdagépre vonatkozó rész opcionális. Ha a `QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS` engedélyezve van, a Queuety először cgroup-memóriaadatokat próbál olvasni, Linux gazdagépeken pedig a `/proc/meminfo` értékhez folyamodik. Ha nem áll rendelkezésre megbízható rendszerszintű pillanatkép, a worker továbbra is a folyamaton belüli ellenőrzéseket használja.

## A workerek számának növelése a kapacitás figyelembevételével

A rögzített workerméretek könnyen átláthatók, de a csendes időszakokra és a terhelési csúcsokra is ugyanazt a számot kell megadni.

Az adaptív pooloknál ehelyett alsó és felső határt állíthat be:

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

A szülőfolyamat legalább a minimális számú gyermekfolyamatot életben tartja, a felvehető hátralék növekedésekor a maximális szám felé bővíti a poolt, majd a várólista beállított inaktivitási türelmi ideje után csökkenti a méretét.

A méretnövelés továbbra is figyelembe veszi a rendelkezésre álló kapacitást. Ha engedélyezve van a rendszermemória figyelése, és a szülő nem lát elegendő szabad memóriát még egy teljes worker számára, a pool méretét változatlanul hagyja ahelyett, hogy további gyermekfolyamatokat indítana.

## A rétegek gyakorlati kombinálása

Képzeljen el egy kutatási munkafolyamatot, amely megtervezi a szolgáltatói hívásokat, szakértői munkafolyamatokat indít, majd összeállítja az eredményt.

A szolgáltatót hívó lépés közzéteheti a `cost_units` és egy megosztott `concurrency_group` értéket, így több worker sem terheli túl egyszerre ugyanazt a modell-szolgáltatót. A várólista súlyozott keretet tarthat fenn az adott szolgáltató forgalmára. A szülő-munkafolyamat korlátozhatja a `max_cost_units()` és a `max_started_workflows()` értékét, így a tervező nem növelheti korlátlanul a futást. Ezután a worker még mindig elhalaszthat egy újonnan átvett szolgáltatói hívást, ha a legutóbbi csúcsmemória-adatok szerint a folyamat vagy a konténer már túl közel van a felső határához.

Ez négy külön szabályozási lehetőséget ad:

1. a munka súlyának leírása
2. megosztott várólista- vagy szolgáltatói kapacitás lefoglalása
3. annak korlátozása, hogy egy futás mennyi munkát hozhat létre
4. a túlterhelt worker visszatartása a szükségesnél több munka indításától

## Hol találhatók a részletes API-k

Ez az oldal az alapelveket tekinti át.

A konkrét beállításokért:

- [Workerek](https://queuety.inline0.dev/hu/docs/features/workers) a felvételi működésről és a futásidejű konstansokról szól
- [CLI](https://queuety.inline0.dev/hu/docs/cli) a rögzített és adaptív workerpool-parancsokat ismerteti
- [Munkafolyamat-védőkorlátok](https://queuety.inline0.dev/hu/docs/workflows/guardrails) a munkafolyamatok kereteiről szól
- [Feladatok](https://queuety.inline0.dev/hu/docs/jobs) a feladatok és kezelők metaadatait ismerteti
- [Állapotgépek](https://queuety.inline0.dev/hu/docs/state-machines) az állapotműveletek erőforrás-metaadatairól szól
- [API](https://queuety.inline0.dev/hu/docs/api) a pontos metódusokat és visszatérési formákat sorolja fel
