
# Mesin Status

Mesin status dan alur kerja menyelesaikan masalah yang berbeda.

Alur kerja menjawab, "pekerjaan apa yang dijalankan berikutnya?" Mesin status menjawab, "apa status benda ini, dan peristiwa apa yang valid dari sini?" Perbedaan itu penting ketika yang Anda bangun bukan sekadar rangkaian langkah, melainkan entitas berumur panjang yang bereaksi terhadap masukan dari luar seiring waktu, seperti sesi agen, utas obrolan, siklus peninjauan, tiket, atau alur persetujuan.

## Contoh singkat

```php
use Queuety\Enums\StateMachineStatus;
use Queuety\Queuety;

$machine_id = Queuety::machine( 'agent_session' )
    ->version( 'agent-session.v1' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'awaiting_review' )
    ->state( 'awaiting_review' )
    ->on( 'approve', 'completed', ReviewApprovedGuard::class )
    ->on( 'reject', 'awaiting_user' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );

Queuety::machine_event(
    $machine_id,
    'user_message',
    [ 'message' => 'Find competitors for this product' ]
);

Queuety::machine_event(
    $machine_id,
    'approve',
    [ 'approved' => true, 'reviewer' => 'editor@example.com' ]
);
```

Mesin ini dimulai di `awaiting_user`, beralih ke `planning` saat pesan pengguna tiba, membiarkan tindakan yang diantrekan mengeluarkan `planned`, lalu menunggu di `awaiting_review` hingga persetujuan eksternal menyelesaikan sesi. Hal yang penting bukan sintaks kodenya sendiri. Yang penting adalah siklus hidupnya dinyatakan secara eksplisit, dapat diperiksa, dan digerakkan oleh peristiwa.

## Cara kerja mesin

Saat instans mesin di-dispatch, Queuety menyimpan nama status saat ini, payload status publik, versi dan hash definisi, peristiwa masuk yang valid untuk status saat ini, serta linimasa peristiwa yang persisten.

Jika status yang dimasuki memiliki `action()`, Queuety mengantrekan job untuk memasuki status tersebut. Tindakan itu dapat sekadar memperbarui status publik dan membiarkan mesin menunggu peristiwa berikutnya, atau dapat mengeluarkan `_event` dan secara opsional `_event_payload` untuk langsung menjalankan transisi berikutnya. Jika status tidak memiliki tindakan dan bukan status terminal, mesin hanya menunggu peristiwa eksternal yang dikirim dengan `Queuety::machine_event()`.

## Memilih antara alur kerja dan mesin status

Gunakan alur kerja ketika proses pada dasarnya berorientasi pada langkah. Ambil data, tunggu untuk setiap pekerjaan, rangkum, lalu selesaikan. Model ini cocok ketika ada awal dan akhir yang jelas, dan pertanyaan utamanya adalah pekerjaan apa yang harus dijalankan berikutnya.

Gunakan mesin status ketika perilaku yang valid bergantung pada fase siklus hidup saat ini. Ini lebih cocok ketika peristiwa dapat tiba dalam urutan berbeda, ketika entitas dapat hidup dalam waktu lama, atau ketika Anda memerlukan pemeriksaan siklus hidup yang eksplisit dengan status seperti `awaiting_user`, `planning`, `running_agents`, `awaiting_review`, dan `completed`.

## Cara keduanya bekerja bersama

Kedua primitif ini paling baik digunakan bersama, bukan saling bersaing. Tindakan status dapat men-dispatch alur kerja ketika transisi memerlukan eksekusi yang lebih berat, dan alur kerja dapat mengirimkan peristiwa kembali ke mesin saat pekerjaan selesai. Dalam praktiknya, mesin status mengatur siklus hidup, sementara alur kerja menjalankan proses yang mahal atau sangat terstruktur.

## Bentuk builder

`StateMachineBuilder` sengaja dibuat tetap kecil. `initial()` dan `state()` mendefinisikan graf siklus hidup. `action()` mengaitkan pekerjaan yang diantrekan ke satu status. `on()` menyatakan peristiwa mana yang dapat memindahkan mesin ke status berikutnya. `on_queue()`, `with_priority()`, dan `max_attempts()` mengatur cara tindakan status dijalankan, sedangkan `version()` dan `idempotency_key()` melampirkan metadata dispatch persisten. `dispatch()` membuat instans mesin.

Tindakan status juga dapat menyediakan metode `config()` opsional dengan menggunakan kunci kebijakan sumber daya yang sama seperti yang digunakan langkah dan handler alur kerja. Dengan begitu, satu transisi status yang mahal dapat ditempatkan dalam grup konkurensi bersama atau diberi bobot biaya lebih tinggi ketika suatu tindakan menghabiskan anggaran lebih besar daripada langkah biasa.

Model sumber daya yang lebih luas dijelaskan di [Manajemen Sumber Daya](https://queuety.inline0.dev/id/docs/features/resource-management).

## Kontrak

Tindakan saat memasuki status mengimplementasikan `Queuety\Contracts\StateAction`:

```php
namespace Queuety\Contracts;

interface StateAction {
    public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string;
}
```

`$payload` adalah payload terstruktur dari definisi tindakan, dan kosong jika tindakan diberikan sebagai nama kelas biasa. Queuety membuat tindakan dengan `new $class()`, sehingga kelas tindakan memerlukan konstruktor tanpa argumen wajib.

Tindakan status juga dapat mendefinisikan metode `config()` opsional dengan `concurrency_group`, `concurrency_limit`, dan `cost_units` jika tindakan masuk yang diantrekan harus turut serta dalam penerimaan worker, anggaran antrean berbobot atau penyedia, serta kebijakan sumber daya lainnya.

Penjaga transisi mengimplementasikan `Queuety\Contracts\StateGuard`:

```php
namespace Queuety\Contracts;

interface StateGuard {
    public function allows( array $state, array $event_payload, string $event, array $payload = [] ): bool;
}
```

## API inspeksi

Gunakan facade untuk memeriksa mesin yang sedang berjalan:

```php
$status   = Queuety::machine_status( $machine_id );
$machines = Queuety::list_machines();
$events   = Queuety::machine_timeline( $machine_id );
$trace    = Queuety::machine_trace( $machine_id );
$state    = Queuety::machine_state_at( $machine_id, $event_id );
```

Mesin status tidak memiliki perintah WP-CLI: `wp queuety workflow ...` hanya mencakup alur kerja. Gunakan API PHP ini, misalnya melalui `wp eval`, untuk memeriksa mesin dari baris perintah.

API tersebut menampilkan nama status saat ini, status siklus hidup, status publik, peristiwa yang tersedia, metadata definisi, linimasa transisi lengkap, dan bundel jejak yang dinormalisasi untuk UI debugger. Baris daftar mesin menyertakan versi definisi, hash definisi, dan kunci idempotensi agar layar daftar dapat menampilkan versi sumber/runtime tanpa memuat setiap mesin secara terpisah. Bundel jejak mencakup status yang dikelompokkan, peristiwa mentah, job tindakan yang berkorelasi, log, referensi artefak, referensi potongan, masukan/keluaran handler, status sebelum/sesudah, konteks, waktu, dan kesalahan terstruktur.

## Sesi agen

Mesin status sangat berguna untuk sistem agen yang perilakunya lebih menyerupai sesi daripada pipeline. Sesi yang bergerak melalui `awaiting_user`, `planning`, `running_agents`, `awaiting_review`, dan `completed` biasanya lebih mudah dipahami sebagai siklus hidup eksplisit daripada sebagai satu definisi alur kerja yang sangat panjang dengan banyak penantian dan jalur balik.

## Lihat juga

- [Neuron Mesin Status Sesi](https://queuety.inline0.dev/id/docs/examples/neuron-session-state-machine)
- [Neuron Mesin Status Memori + Peninjauan](https://queuety.inline0.dev/id/docs/examples/neuron-memory-review)
- [Orkestrasi Agen](https://queuety.inline0.dev/id/docs/workflows/agent-orchestration)
- [Sinyal Alur Kerja](https://queuety.inline0.dev/id/docs/workflows/signals)
- [Dependensi Alur Kerja](https://queuety.inline0.dev/id/docs/workflows/dependencies)
- [Pengulangan](https://queuety.inline0.dev/id/docs/workflows/repeats)
- [Artefak](https://queuety.inline0.dev/id/docs/features/artifacts)
- [PHP API](https://queuety.inline0.dev/id/docs/api)
