
# Pengelolaan sumber daya

Queuety membagi kontrol sumber daya menjadi empat lapisan inti, ditambah pengaturan ukuran pool opsional.

Lapisan pertama menjelaskan seberapa besar biaya satu unit pekerjaan. Lapisan kedua membatasi tekanan bersama yang boleh ditanggung satu antrean atau grup penyedia sekaligus. Lapisan ketiga menetapkan jumlah yang boleh digunakan oleh satu eksekusi alur kerja. Lapisan keempat menentukan apakah worker harus segera memulai pekerjaan berikutnya yang telah diambil atau menundanya sampai proses dan kontainer saat ini memiliki kapasitas yang cukup.

Lapisan-lapisan ini bekerja bersama. Handler dapat menyatakan bahwa ia termasuk dalam pool bersama yang mahal, antrean dapat mencadangkan sejumlah pekerjaan berbobot untuk satu penyedia, alur kerja dapat membatasi jumlah pekerjaan semacam itu yang akan dibuatnya, dan worker tetap dapat menolak memulai lebih banyak pekerjaan ketika proses atau kontainer saat ini sudah terlalu dekat dengan batasnya.

## Menjelaskan biaya satu unit pekerjaan

Pekerjaan, langkah alur kerja, dan tindakan saat memasuki status semuanya dapat menerbitkan tiga petunjuk sumber daya yang sama:

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

`concurrency_group` dan `concurrency_limit` menjelaskan tekanan bersama pada satu sistem hilir. Jika beberapa handler mengakses penyedia, akun API, atau tenant yang sama, mereka dapat menggunakan grup yang sama agar worker tidak memulai terlalu banyak pekerjaan sekaligus.

`cost_units` menjelaskan bobot relatif. Penyegaran cache dan panggilan besar ke penyedia mungkin sama-sama merupakan “satu pekerjaan”, tetapi keduanya seharusnya tidak berkontribusi sama besar saat anggaran alur kerja atau aturan penerimaan worker menentukan apakah pekerjaan tambahan masih aman.

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

Gagasan yang sama berlaku untuk pekerjaan yang dapat dikirim melalui properti kelas, dan untuk pengiriman individual melalui `PendingJob::concurrency_group()` dan `PendingJob::cost_units()`.

## Menganggarkan antrean bersama dan grup penyedia

Tekanan bersama tidak selalu berupa hitungan konkurensi sederhana. Terkadang bagian yang mahal adalah bobot gabungan dari pekerjaan yang sudah berjalan.

Queuety mendukungnya melalui anggaran antrean dan grup berbobot. Anggaran antrean menggunakan nama antrean sebagai kunci. Anggaran grup menggunakan `concurrency_group` sebagai kunci, sehingga handler yang tidak terkait dapat berpartisipasi dalam batas bersama yang sama.

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

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

Saat mengambil pekerjaan, worker memeriksa baris `processing` aktif yang sudah termasuk dalam antrean atau grup tersebut. Jika biaya yang sedang berjalan ditambah `cost_units` pekerjaan yang baru diambil akan melampaui anggaran yang dikonfigurasi, worker melepas pekerjaan itu dan mencoba lagi nanti.

Ini memberi Anda kontrol yang berbeda dari `concurrency_limit`. Penyedia dapat mengizinkan tiga permintaan serentak, tetapi tetap menyediakan lebih sedikit unit biaya total untuk permintaan besar daripada permintaan kecil.

## Menjaga satu alur kerja tetap dalam batas

Anggaran alur kerja berguna saat masalahnya bukan satu pekerjaan berat, melainkan eksekusi yang terus menemukan lebih banyak pekerjaan daripada yang direncanakan.

Hal ini umum terjadi pada sistem berbasis agen. Perencana mungkin mengunjungi kembali cabang mahal yang sama, membaginya menjadi terlalu banyak subtugas, atau terus memulai alur kerja anak sambil tetap berada dalam model percobaan ulang yang normal.

Queuety menyediakan batas tingkat alur kerja untuk itu:

```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()` mencegah eksekusi menggunakan lebih banyak pekerjaan berbobot daripada yang direncanakan. `max_started_workflows()` mencegah induk berubah menjadi pohon eksekusi anak tingkat atas yang tak terbatas. Batas pengaman lainnya tetap penting karena tidak semua alur kerja yang berjalan tak terkendali memiliki biaya yang sama.

Status alur kerja menampilkan batas yang dikonfigurasi dan penggunaan saat ini melalui payload publik `budget`, sehingga eksekusi tetap dapat diperiksa selama batas tersebut aktif.

## Membiarkan worker menunda pekerjaan saat proses sudah terlalu penuh

Meskipun metadata dan anggaran alur kerja telah dikonfigurasi dengan baik, keputusan akhir tetap berada pada proses worker yang akan menjalankan pekerjaan.

Di sinilah penerimaan yang sadar sumber daya berperan. Sebelum pekerjaan yang telah diambil dimulai, Queuety dapat memeriksa:

- grup konkurensi bersama milik pekerjaan
- anggaran berbobot untuk antrean dan grup penyedia
- riwayat durasi terbaru dan penggunaan memori puncak untuk handler
- sisa kapasitas memori worker saat ini
- sisa kapasitas memori kontainer atau host saat ini
- sisa rentang waktu untuk eksekusi bergaya sekali jalan

Jika worker sudah terlalu dekat dengan batas yang dikonfigurasi, Queuety melepas pekerjaan alih-alih memulai pekerjaan yang kemungkinan besar tidak akan selesai dengan baik.

Pendekatan ini sengaja dibuat konservatif. Ini bukan penjadwal cluster yang lengkap. Ini adalah lapisan keselamatan yang membantu worker sibuk menghindari penggunaan sumber daya proses tempatnya berjalan secara berlebihan, serta kontainer atau host di sekitarnya jika telemetri memori tersedia.

Bagian kontainer atau host bersifat opsional. Saat `QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS` diaktifkan, Queuety mencoba membaca data memori cgroup terlebih dahulu dan beralih ke `/proc/meminfo` pada host Linux jika gagal. Jika snapshot tingkat sistem yang andal tidak tersedia, worker tetap menggunakan pemeriksaan lokal proses.

## Menskalakan pool worker dengan memperhatikan kapasitas

Pool worker tetap mudah dipahami, tetapi mengharuskan Anda memilih satu angka untuk masa sepi maupun lonjakan.

Pool adaptif memungkinkan Anda menetapkan batas bawah dan batas atas:

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

Proses induk menjaga setidaknya jumlah minimum proses anak tetap berjalan, menambah jumlahnya hingga batas maksimum saat antrean pekerjaan yang dapat diambil meningkat, lalu menguranginya setelah antrean tidak aktif selama jangka tenggang idle yang dikonfigurasi.

Peningkatan skala tetap memperhatikan kapasitas yang tersedia. Jika kesadaran memori sistem diaktifkan dan proses induk tidak melihat cukup memori tersisa untuk satu alokasi penuh worker, ukuran pool tidak berubah alih-alih memulai lebih banyak proses anak.

## Cara realistis menggabungkan lapisan-lapisan ini

Bayangkan sebuah alur kerja riset yang merencanakan panggilan ke penyedia, memulai alur kerja spesialis, lalu menyintesis hasilnya.

Langkah yang mengakses penyedia dapat menerbitkan `cost_units` dan `concurrency_group` bersama agar beberapa worker tidak menyerbu penyedia model yang sama. Antrean dapat mencadangkan anggaran berbobot untuk lalu lintas penyedia tersebut. Alur kerja induk dapat membatasi `max_cost_units()` dan `max_started_workflows()` agar perencana tidak dapat terus memperbesar eksekusi. Kemudian worker tetap dapat menunda panggilan ke penyedia yang baru diambil jika data memori puncak terbaru menunjukkan proses atau kontainer sudah terlalu dekat dengan batasnya.

Dengan begitu, Anda mendapatkan empat kontrol terpisah:

1. jelaskan bobot pekerjaan
2. cadangkan kapasitas bersama untuk antrean atau penyedia
3. batasi jumlah yang boleh dibuat oleh satu eksekusi
4. cegah worker yang sibuk memulai pekerjaan melebihi batas

## Tempat menemukan API terperinci

Halaman ini adalah ikhtisar konseptual.

Untuk opsi yang lebih konkret:

- [Pekerja](https://queuety.inline0.dev/id/docs/features/workers) membahas perilaku penerimaan dan konstanta runtime
- [CLI](https://queuety.inline0.dev/id/docs/cli) membahas perintah pool worker tetap dan adaptif
- [Batas Pengaman Alur Kerja](https://queuety.inline0.dev/id/docs/workflows/guardrails) membahas anggaran alur kerja
- [Pekerjaan](https://queuety.inline0.dev/id/docs/jobs) membahas metadata pekerjaan dan handler
- [Mesin Status](https://queuety.inline0.dev/id/docs/state-machines) membahas metadata sumber daya untuk tindakan status
- [API](https://queuety.inline0.dev/id/docs/api) memuat metode dan bentuk nilai kembalian yang tepat
