
# Resursu pārvaldība

Queuety sadala resursu kontroli četros pamatslāņos, kam papildus var pievienot kopas lieluma noteikšanu.

Pirmais slānis apraksta, cik dārga ir viena darba vienība. Otrais ierobežo kopīgo slodzi, ko vienlaikus drīkst radīt viena rinda vai pakalpojumu sniedzēju grupa. Trešais nosaka, cik daudz drīkst patērēt viena darbplūsmas izpilde. Ceturtais izlemj, vai darbiniekam nekavējoties jāsāk nākamais paņemtais darbs vai tas jāatliek, līdz pašreizējā procesā un konteinerā atkal ir pietiekama rezerve.

Šie slāņi darbojas kopā. Apdarinātājs var norādīt, ka tas pieder dārgam koplietotam resursu kopumam, rinda var rezervēt vienam pakalpojumu sniedzējam noteiktu svērto darba apjomu, darbplūsma var ierobežot, cik daudz šāda darba tā ir gatava radīt, un darbinieks joprojām var atteikties sākt vairāk šāda darba, ja pašreizējais process vai konteiners jau ir pārāk tuvu saviem limitiem.

## Viena darba vienības izmaksu aprakstīšana

Darbi, darbplūsmas soļi un stāvokļa ievades darbības var publicēt vienus un tos pašus trīs resursu padomus:

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

`concurrency_group` un `concurrency_limit` apraksta kopīgo slodzi uz vienu pakārtoto sistēmu. Ja vairāki apdarinātāji piekļūst vienam pakalpojumu sniedzējam, API kontam vai nomniekam, tie var izmantot vienu un to pašu grupu, lai darbinieki vienlaikus nesāktu pārāk daudz darbu.

`cost_units` apraksta relatīvo svaru. Kešatmiņas atsvaidzināšana un liels pakalpojumu sniedzēja izsaukums var būt “viens darbs”, taču tiem nevajadzētu būt vienādiem, kad darbplūsmas budžets vai darbinieka piekļuves noteikums lemj, vai ir droši sākt vēl darbus.

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

Tas pats princips attiecas uz nosūtāmiem darbiem, kuriem tas norādīts klases īpašībās, un uz atsevišķiem nosūtīšanas gadījumiem, izmantojot `PendingJob::concurrency_group()` un `PendingJob::cost_units()`.

## Koplietojamo rindu un pakalpojumu sniedzēju grupu budžeta noteikšana

Kopīgo slodzi ne vienmēr mēra ar vienkāršu vienlaicīguma skaitu. Dažkārt dārgāko daļu veido jau izpildē esošā darba kopējais svars.

Queuety to atbalsta ar svērtiem rindu un grupu budžetiem. Rindu budžetu atslēga ir rindas nosaukums. Grupas budžetu atslēga ir `concurrency_group`, kas ļauj nesaistītiem apdarinātājiem piedalīties vienā kopīgā budžetā.

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

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

Kad darbinieks paņem darbu, tas pārbauda aktīvos `processing` ierakstus, kas jau pieder šai rindai vai grupai. Ja pašreizējo darbu izmaksas kopā ar paņemtā darba `cost_units` pārsniegtu konfigurēto budžetu, darbinieks atlaiž darbu un mēģina vēlreiz vēlāk.

Tas ļauj kontrolēt slodzi citādi nekā ar `concurrency_limit`. Pakalpojumu sniedzējs var atļaut trīs vienlaicīgus pieprasījumus, taču lielākiem pieprasījumiem rezervēt mazāk kopējo izmaksu vienību nekā mazākiem.

## Darbplūsmas ierobežošana noteiktās robežās

Darbplūsmu budžeti noder gadījumos, kad problēma nav viens smags darbs, bet gan izpilde, kas turpina atrast vairāk darba, nekā paredzēts.

Tas bieži notiek aģentiskās sistēmās. Plānotājs var atkārtoti apmeklēt to pašu dārgo atzaru, sadalīt to pārāk daudzos apakšuzdevumos vai turpināt sākt pakārtotās darbplūsmas, lai gan formāli tiek ievērots parastais atkārtošanas modelis.

Queuety šim nolūkam nodrošina darbplūsmas līmeņa ierobežojumus:

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

`max_cost_units()` neļauj izpildei patērēt vairāk svērtā darba, nekā paredzēts. `max_started_workflows()` neļauj vecākprocesam izveidot neierobežotu koku ar augstākā līmeņa pakārtotajām izpildēm. Pārējie aizsardzības mehānismi joprojām ir svarīgi, jo ne visas nekontrolējamas darbplūsmas rada vienāda veida izmaksas.

Darbplūsmas statusā, izmantojot publisko `budget` datu objektu, ir redzami konfigurētie limiti un pašreizējais patēriņš, tāpēc izpildi var pārraudzīt, kamēr šie limiti ir spēkā.

## Ļaut darbiniekiem atlikt darbu, ja process jau ir pārāk noslogots

Pat tad, ja metadati un darbplūsmas budžeti ir pareizi konfigurēti, galīgo lēmumu tik un tā pieņem darbinieka process, kas gatavojas izpildīt darbu.

Šeit noder resursu apzināta darbu pieņemšana. Pirms paņemta darba izpildes sākšanas Queuety var pārbaudīt:

- darba kopīgo vienlaicīguma grupu
- svērtos rindu un pakalpojumu sniedzēju grupu budžetus
- apdarinātāja neseno izpildes laiku un maksimālās atmiņas patēriņa vēsturi
- pašreizējā darbinieka atlikušo atmiņas rezervi
- pašreizējā konteinera vai resursdatora atlikušo atmiņas rezervi
- atlikušā laika robežu vienreizējas izpildes tipa darbībām

Ja darbinieks jau ir pārāk tuvu konfigurētajam ierobežojumam, Queuety atlaiž darbu, nevis sāk darbu, kuru, visticamāk, nevarēs pabeigt bez problēmām.

Šī pieeja ir apzināti piesardzīga. Tas nav pilnvērtīgs klastera plānotājs. Tas ir drošības slānis, kas palīdz noslogotam darbiniekam nepārslogot procesu, kurā tas darbojas, un, ja pieejama atmiņas telemetrija, arī apkārtējo konteineru vai resursdatoru.

Konteinera vai resursdatora pārbaude nav obligāta. Kad `QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS` ir iespējots, Queuety vispirms mēģina nolasīt cgroup atmiņas datus un Linux resursdatoros, ja tas neizdodas, izmanto `/proc/meminfo`. Ja nav pieejams uzticams sistēmas līmeņa momentuzņēmums, darbinieks tik un tā turpina izmantot lokālos procesa līmeņa pārbaužu datus.

## Darbinieku kopu mērogošana, ņemot vērā jaudu

Fiksētu darbinieku kopu darbību ir viegli paredzēt, taču tad ir jāizvēlas viens skaitlis gan mierīgiem periodiem, gan slodzes lēcieniem.

Pielāgojamas kopas ļauj tā vietā iestatīt apakšējo un augšējo robežu:

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

Vecākprocess uztur dzīvus vismaz minimālo skaitu pakārtoto procesu, palielina to skaitu līdz maksimālajam, pieaugot rindā esošajam paņemamajam darbu skaitam, un samazina to pēc tam, kad rinda konfigurēto dīkstāves periodu ir bijusi klusa.

Mērogošana uz augšu joprojām ņem vērā pieejamo jaudu. Ja ir iespējota sistēmas atmiņas uzraudzība un vecākprocess neredz pietiekami daudz atlikušās atmiņas vēl vienai pilnai darbinieka resursu rezervei, tas saglabā pašreizējo kopas lielumu un nesāk jaunus pakārtotos procesus.

## Reālistisks slāņu apvienošanas piemērs

Iedomājieties izpētes darbplūsmu, kas plāno izsaukumus pakalpojumu sniedzējiem, sāk specializētas darbplūsmas un pēc tam sintezē rezultātu.

Pakalpojumu sniedzējam paredzētais solis var norādīt `cost_units` un kopīgo `concurrency_group`, lai vairāki darbinieki vienlaikus nepieprasītu vienu un to pašu modeļa nodrošinātāju. Rinda var rezervēt svērtu budžetu šī pakalpojumu sniedzēja datplūsmai. Vecākdarbplūsma var ierobežot `max_cost_units()` un `max_started_workflows()`, lai plānotājs nevarētu bezgalīgi paplašināt izpildi. Pēc tam darbinieks joprojām var atlikt tikko paņemtu pieprasījumu pakalpojumu sniedzējam, ja nesenie maksimālās atmiņas patēriņa dati liecina, ka process vai konteiners jau ir pārāk tuvu savam limitam.

Tādējādi ir pieejamas četras atsevišķas kontroles:

1. aprakstīt darba svaru
2. rezervēt koplietojamās rindas vai pakalpojumu sniedzēja jaudu
3. ierobežot to, cik daudz drīkst radīt viena izpilde
4. neļaut noslogotam darbiniekam sākt vairāk darbu, nekā vajadzētu

## Kur atrodamas detalizētās API

Šī lapa ir konceptuāls pārskats.

Detalizētus iestatījumus skatiet šeit:

- [Darbinieki](https://queuety.inline0.dev/lv/docs/features/workers) apraksta pieņemšanas darbību un izpildlaika konstantes
- [CLI](https://queuety.inline0.dev/lv/docs/cli) apraksta fiksēta un adaptīva darbinieku kopuma komandas
- [Darbplūsmu ierobežojumi](https://queuety.inline0.dev/lv/docs/workflows/guardrails) apraksta darbplūsmu budžetus
- [Uzdevumi](https://queuety.inline0.dev/lv/docs/jobs) apraksta uzdevumu un apdarinātāju metadatus
- [Stāvokļu mašīnas](https://queuety.inline0.dev/lv/docs/state-machines) apraksta stāvokļu darbību resursu metadatus
- [API](https://queuety.inline0.dev/lv/docs/api) uzskaita precīzās metodes un atgriežamo vērtību struktūras
