
# Varnostne omejitve delovnega toka

Delovni tokovi v slogu agentov so prilagodljivi, vendar lahko zaradi njih lažje ustvarite podvojena izvajanja ali načrtovalniku dovolite, da ustvari več dela, kot je predvideno. Queuety na ravni delovnega toka zagotavlja preproste varovalke, s katerimi ohranite prilagodljivost in hkrati nadzor.

Za širši model virov, ki zajema sprejemanje delavcev in metapodatke o stroških posameznih opravil, glejte [Upravljanje virov](https://queuety.inline0.dev/sl/docs/features/resource-management).

## Različica definicije delovnega toka

Uporabite `version()`, da definiciji delovnega toka pripnete oznako različice na ravni aplikacije:

```php
Queuety::workflow( 'research_run' )
    ->version( 'research.v2' )
    ->then( PlanResearchStep::class )
    ->then( DraftResearchSummaryStep::class )
    ->dispatch();
```

Različica se shrani skupaj s stanjem delovnega toka, prikaže prek `workflow_status()`, izpiše z `wp queuety workflow status` in vključi v izvoze delovnega toka.

Queuety shrani tudi deterministični `definition_hash` za vsako izvajanje delovnega toka. Zgoščena vrednost je izpeljana iz serializirane definicije delovnega toka in je uporabna, ko morate po namestitvi natančno ugotoviti, katero obliko delovnega toka izvaja trenutno tekoče izvajanje.

## Zagotovite idempotentnost odpreme

Uporabite `idempotency_key()`, kadar lahko klicatelji ponovijo isto zahtevo:

```php
Queuety::workflow( 'research_run' )
    ->idempotency_key( 'brief:42:research' )
    ->then( PlanResearchStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );
```

Če delovni tok znova odpošljete s ključem, ki je že bil uporabljen, Queuety vrne ID izvirnega delovnega toka, namesto da bi ustvaril podvojeno izvajanje. Ključi so skupni vsem imenom delovnih tokov, zato v ključ vključite ime delovnega toka, če bi ga lahko uporabljali različni delovni tokovi.

To je posebej uporabno za:

- končne točke API, pri katerih lahko odjemalci ali prehodi ponovijo zahtevo
- porabnike spletnih kavljev, ki lahko prejmejo podvojene dostave
- korake načrtovalnika, ki naj ustvarijo le eno orkestracijsko izvajanje na zunanjo entiteto

Idempotentni ključi so shranjeni v tabeli `queuety_workflow_dispatch_keys`.

## Nastavite proračune delovnega toka

S proračuni delovnega toka lahko neuspešno zaključite izvajanja, ki presežejo načrtovane omejitve:

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

Omeji število korakov delovnega toka, ki se lahko zaključijo, preden izvajanje ne uspe. To je uporabno za zaščito delovnih tokov, ki se dinamično razvejajo ali se lahko prek `_next_step` vrnejo na isto mesto.

### `max_for_each_items()`

Omeji število elementov, odkritih med izvajanjem, ki jih lahko razširi posamezen korak `for_each()`. To je uporabno pri sistemih načrtovalnik/izvajalnik, kjer bi agent lahko odkril veliko več dela za veje, kot je predvideno.

### `max_state_bytes()`

Omeji kodirano velikost javnega stanja delovnega toka. To prepreči, da bi se dolgotrajni delovni tokovi razrasli v velike zbirke podatkov, ki jih je težko pregledovati, izvažati ali ponovno uvrstiti v čakalno vrsto.

### `max_cost_units()`

Omeji skupno število stroškovnih enot, ki jih porabijo zaključeni koraki. Stroškovne enote izhajajo iz metapodatkov koraka ali opravila, ki jih Queuety razreši ob uvrstitvi dela v čakalno vrsto. Običajno uporabniško delo ima privzeto vrednost `1`, nadomestna orkestracijska opravila, kot so zamiki in čakanja, uporabljajo `0`, obdelovalniki pa lahko prek `config()` ali lastnosti opravila nastavijo višjo pozitivno vrednost. Vrednost `0` lahko nastavi samo `cost_units` definicije koraka.

To je uporabno, kadar se delovni tok lahko vrne na isto mesto ali kadar for-each razširi v delo, ki je drago iz razlogov, ki jih samo število korakov ne zajame. Načrtovalnik, ki znova in znova kliče drag model, lahko ostane znotraj `max_transitions()`, a vseeno preseže predvideni stroškovni proračun.

### `max_started_workflows()`

Omeji število delovnih tokov najvišje ravni, ki jih lahko izvajanje zažene prek `start_workflows()` ali `start_agents()`. Omejitev se preveri, preden se podrejeni delovni tokovi odpošljejo, zato nadrejeni delovni tok ne uspe, ne da bi delno ustvaril skupino, ki že presega proračun.

Ko je proračun presežen, Queuety takoj označi delovni tok kot neuspešen, namesto da bi ponovil korak. Izjema: ko `Queuety::signal()` zaključi čakanje in posledični prehod preseže proračun, se izjema posreduje klicatelju `signal()`, vstavljanje signala se razveljavi, delovni tok pa še naprej čaka.

## Spremljanje varovalk

Stanje delovnega toka prikazuje:

- `definition_version`
- `definition_hash`
- `idempotency_key`
- `budget`

Vsebina `budget` vključuje nastavljene omejitve in trenutno porabo, vključno s trenutno velikostjo javnega stanja v bajtih.

Primer:

```php
$state = Queuety::workflow_status( $workflow_id );

$state->definition_version; // 'research.v2'
$state->definition_hash;    // '4c7a...'
$state->idempotency_key;    // 'brief:42:research'
$state->budget;             // [ 'max_transitions' => 20, ... ]
```
