
# Darbo eigos

Darbo eigos suskaido ilgai trunkantį darbą į atskirus žingsnius. Kiekvieno žingsnio išvestis išsaugoma duomenų bazėje, bendroje būsenos struktūroje. Jei PHP nutrūksta žingsnio viduryje, darbuotojas pakartoja šį žingsnį, išsaugodamas visą ankstesnę būseną.

## Kas yra darbo eigos?

Darbo eiga yra nuosekli žingsnių seka. Kiekvienas žingsnis yra PHP klasė, kuriai perduodama visų ankstesnių žingsnių sukaupta būsena ir kuri grąžina naujus duomenis, sujungiamus su būsena. Darbo eiga juda po vieną žingsnį, o kiekvienas perėjimas vykdomas atominėje MySQL transakcijoje.

```php
use Queuety\Queuety;

$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

## Būsenos kaupimas

Pradinė naudingoji apkrova, kurią perduodate `dispatch()`, tampa pradine būsena. Kiekvieno žingsnio grąžinami raktai sujungiami su būsena. Raktais, prasidedančiais `_`, rezervuojamos valdymo reikšmės, pavyzdžiui, `_next_step`; jie nesujungiami su viešąja būsena:

```
dispatch(['user_id' => 42])

Step 0: FetchDataHandler   -> returns ['user_name' => 'Alice']
  state: {user_id: 42, user_name: 'Alice'}

Step 1: CallLLMHandler     -> returns ['llm_response' => '...']
  state: {user_id: 42, user_name: 'Alice', llm_response: '...'}

Step 2: FormatOutputHandler -> returns ['report_url' => '/reports/42.pdf']
  state: {user_id: 42, user_name: 'Alice', llm_response: '...', report_url: '/reports/42.pdf'}
```

Kiekvienas žingsnis mato visą sukauptą būseną. Taip lengva perduoti duomenis tarp žingsnių nenaudojant išorinės saugyklos.

## Tęsimas

Darbo eigos yra patikimos, nes po kiekvieno žingsnio būsena išsaugoma duomenų bazėje. Jei darbuotojas sugenda vykdydamas 1 žingsnį, darbo eiga paleidžiama iš naujo nuo 1 žingsnio, o 0 žingsnio išvestis jau būna įrašyta būsenoje.

Žingsnio riba yra viena MySQL transakcija, kuri atominiu būdu:
1. Atnaujina darbo eigos būseną žingsnio išvestimi
2. Pažymi dabartinio žingsnio užduotį kaip užbaigtą
3. Įtraukia kito žingsnio užduotį į eilę

Taip užtikrinama, kad būsena niekada nebūtų prarasta net įvykus gedimams, pasibaigus skirtajam laikui ar ištikus PHP kritinėms klaidoms.

## Darbo eigos gyvavimo ciklas

```
dispatch() -> running -> step 0 -> step 1 -> ... -> step N -> completed
                  |                   |
                  |                   +-> failed -> retry -> running (from failed step)
                  |
                  +-> paused -> resumed -> running
                  |
                  +-> waiting_for_signal -> signal received -> running
                  |
                  +-> waiting_for_workflows -> dependency settles -> running
                  |
                  +-> cancelled (via cancel_workflow)
```

| Būsena | Aprašymas |
|---|---|
| `running` | Aktyviai vykdomi žingsniai |
| `completed` | Visi žingsniai sėkmingai užbaigti |
| `failed` | Žingsnis nepavyko išnaudojus pakartotinių bandymų skaičių |
| `paused` | Pristabdyta rankiniu būdu. Šiuo metu vykdomas darbas gali būti užbaigtas, bet vėlesni žingsniai neįtraukiami į eilę, kol darbo eiga neatnaujinama |
| `waiting_for_signal` | Laukiama išorinio signalo per `Queuety::signal()` |
| `waiting_for_workflows` | Laukiama, kol viena ar daugiau kitų darbo eigų bus užbaigtos per `wait_for_workflow()` arba `wait_for_workflows()` |
| `cancelled` | Aiškiai atšaukta per `Queuety::cancel_workflow()`. Laukiančios užduotys užkasamos ir paleidžiama pasirinktinė valymo apdorojimo funkcija. |

## Darbo eigų valdymas

Patikrinkite būseną:

```php
$state = Queuety::workflow_status( $workflow_id );
echo $state->status->value;   // 'running'
echo $state->current_step;    // 1
echo $state->total_steps;     // 3
print_r( $state->waiting_for ); // ['42'] while waiting on another workflow
print_r( $state->wait_details ); // matched/remaining blockers, result key, correlation info
```

Pristabdykite ir tęskite:

```php
Queuety::pause_workflow( $workflow_id );
Queuety::resume_workflow( $workflow_id );
```

Pakartokite nepavykusią darbo eigą nuo nepavykusio žingsnio:

```php
Queuety::retry_workflow( $workflow_id );
```

Atšaukite darbo eigą ir paleiskite valymo apdorojimo funkcijas:

```php
Queuety::cancel_workflow( $workflow_id );
```

Išsamesnės informacijos apie valymo apdorojimo funkcijas ir tai, kas nutinka atšaukus darbo eigą, žr. [Atšaukimas](https://queuety.inline0.dev/lt/docs/workflows/cancellation).

## Darbo eigos parinktys

Nustatykite visų darbo eigos žingsnių eilę, prioritetą ir pakartotinių bandymų elgseną:

```php
use Queuety\Enums\Priority;

Queuety::workflow( 'important_pipeline' )
    ->on_queue( 'pipelines' )
    ->with_priority( Priority::High )
    ->max_attempts( 5 )
    ->on_cancel( PipelineCleanupHandler::class )
    ->prune_state_after( 3 )
    ->then( StepA::class )
    ->then( StepB::class )
    ->dispatch( $payload );
```

Metodas `on_cancel()` užregistruoja valymo apdorojimo funkciją, kuri paleidžiama atšaukus darbo eigą. Žr. [Atšaukimas](https://queuety.inline0.dev/lt/docs/workflows/cancellation).

Metodas `prune_state_after()` įjungia automatinį senų žingsnių išvesčių šalinimą, kad darbo eigos būsena išliktų riboto dydžio. Žr. [Būsenos apkarpymas](https://queuety.inline0.dev/lt/docs/features/state-pruning).

Naudokite `compensate_with()`, kad pridėtumėte kiekvieno žingsnio kompensavimo apdorojimo funkciją. Naudokite `compensate_on_failure()`, jei norite, kad po darbo eigos nesėkmės automatiškai būtų vykdomos užbaigtų žingsnių kompensavimo funkcijos, o ne tik aiškiai atšaukus darbo eigą. Žr. [Kompensavimas](https://queuety.inline0.dev/lt/docs/workflows/compensation).

Naudokite darbo eigos apsaugos priemones, kai reikia saugiau vykdyti ilgai trunkančią orkestraciją: `version()` pažymi apibrėžtį programos lygmens versija, Queuety taip pat išsaugo kiekvieno vykdymo deterministinę apibrėžties maišą, `idempotency_key()` užtikrina patikimą išsiuntimą vykdyti pakartotinių bandymų arba pasikartojančių užklausų atveju, o `max_transitions()`, `max_for_each_items()` ir `max_state_bytes()` sustabdo nekontroliuojamus vykdymus dar prieš jiems įsibėgėjant. Žr. [Apsaugos priemonės](https://queuety.inline0.dev/lt/docs/workflows/guardrails).

## Žingsnių tipai

Queuety palaiko vienuolika darbo eigos žingsnių tipų:

- [Nuoseklios grandinės](https://queuety.inline0.dev/lt/docs/workflows/chains) naudojant `->then()`, kad veiksmai būtų vykdomi po vieną
- [Lygiagrečios grupės](https://queuety.inline0.dev/lt/docs/workflows/parallel) naudojant `->parallel()`, kad veiksmai būtų vykdomi vienu metu
- [Dinaminis vykdymas kiekvienam elementui](https://queuety.inline0.dev/lt/docs/workflows/for-each) naudojant `->for_each()`, skirtą vykdymo metu aptinkamoms šakų užduotims ir aiškiai užbaigimo semantikai
- [Asinchroninis perdavimas](https://queuety.inline0.dev/lt/docs/workflows/async-handoffs) naudojant `->start_workflows()` arba `->start_agents()`, kad iš vykdymo metu aptiktų elementų būtų paleistos nepriklausomos antrinės darbo sekos
- [Sąlyginis šakojimas](https://queuety.inline0.dev/lt/docs/workflows/conditional) naudojant pavadintus veiksmus ir `_next_step`
- [Kartojimai](https://queuety.inline0.dev/lt/docs/workflows/repeats) naudojant `->repeat_until()` ir `->repeat_while()`, kad būtų galima patikimai grįžti prie ankstesnių pavadintų veiksmų
- [Darbo sekų paleidimas](https://queuety.inline0.dev/lt/docs/workflows/run-workflows) naudojant `->run_workflow()` įdėtinei kompozicijai
- [Patikimos delsos](https://queuety.inline0.dev/lt/docs/workflows/delays) naudojant `->delay()` laiko delsoms
- [Signalai](https://queuety.inline0.dev/lt/docs/workflows/signals) naudojant `->wait_for_signal()`, `->wait_for_signals()`, `->wait_for_approval()`, `->wait_for_input()` ir `->wait_for_decision()` išorinių įvykių trigeriams
- [Darbo sekų priklausomybės](https://queuety.inline0.dev/lt/docs/workflows/dependencies) naudojant `->wait_for_workflow()`, `->wait_for_workflows()` ir `->wait_for_agents()` skirtingų darbo sekų koordinavimui
- [Srautiniai veiksmai](https://queuety.inline0.dev/lt/docs/workflows/streaming) naudojant `StreamingStep` sąsają, skirtą patikimai išvesti duomenis dalimis

## Dažni šablonai

Jei kuriate autonomines arba iš dalies autonomines sistemas, pradėkite nuo [Agentų orkestravimas](https://queuety.inline0.dev/lt/docs/workflows/agent-orchestration). Čia parodoma, kaip `for_each()`, `start_agents()`, `wait_for_agents()`, `wait_for_workflow()` ir `wait_for_decision()` dera tarpusavyje realiose planavimo ir vykdymo bei žmogaus peržiūros darbo sekose.
