Semantik eksekusi, batasan, dan keamanan
Terakhir diperbarui: 21 Juli 2026
Halaman ini merangkum bagaimana Script berperilaku saat runtime (urutan, transaksi, error, penguncian), batasan statis apa yang dikenakan saat disimpan, dan model keamanannya. Untuk sintaksis, lihat Katalog Statement dan Ekspresi nilai; untuk kombinasi praktis, lihat Cookbook.
Urutan dan mode eksekusi
statementsdieksekusi secara berurutan dari atas ke bawah. Ketika mencapaiReturn, eksekusi berhenti di titik tersebut.- Sync berjalan pada jalur penanganan permintaan, sedangkan Async berjalan di latar belakang. Ini hanya perbedaan lokasi eksekusi; hasilnya tetap berupa nilai
Returndi kedua kasus (untuk bentuk respons pemanggilan, lihat Permintaan dan respons di Ikhtisar Script dan Mode eksekusi). - Dari kapabilitas ke mode: jika pohon statement mengandung salah satu dari
ExternalIo(panggilan eksternalHttp),MediaIngest(penyerapan file Media;{ source, encoding }di dalamfields.file; berlaku untuk url dan base64), atauLongRunning(Loop berukuran besar, dsb.), makaexecutionModedipaksa menjadiAsync. Ketiganya merupakan kapabilitas yang terpisah, dan masing-masing dihitung terhadap batas yang berbeda seperti pada Batasan statis di bawah.
Semantik eksekusi
Guard (prakondisi)
Tidak ada statement guard khusus. Anda menyatakannya dengan If dan then:[Return]. Ketika kondisi dilanggar, ia mengembalikan hasil dan tidak menjalankan statement selanjutnya (tentu saja Script tanpa guard juga dimungkinkan).
{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
"then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }Tanpa transaksi dan kompensasi best-effort
Script bukanlah transaksi. Saat gagal, engine mencoba mengompensasi (compensation) pekerjaan yang telah dilakukan sejauh ini dan mengembalikan penyebab error, tetapi dengan keterbatasan berikut (diterima sebagai konsekuensi desain).
- Membatalkan penghapusan membuat
sys.idbaru, sehingga referensi yang tadinya menunjuk ke sana menjadi rusak (rollback pembuatan itu mudah; pengubahan memerlukan before-image). - Efek eksternal (
Http) bersifat ireversibel (panggilan yang sudah keluar beserta biayanya tidak dapat dibatalkan). - Saat proses mengalami crash, keadaan yang belum terkompensasi (orphan) dapat tertinggal.
Jika Anda membutuhkan atomisitas sejati, tulis sendiri kompensasi di dalam Script tersebut, atau tempatkan operasi yang tidak dapat dibatalkan (misalnya panggilan eksternal) di paling akhir. Urutan yang paling berbahaya adalah yang "berhasil dirantai tetapi tidak dapat di-rollback, namun tampak aman."
Penguncian optimis
Persaingan update/patch dipersempit dengan version pada ResourceUpdate dan ResourcePatch. Jika Anda memberikan version (ekspresi nilai, Int), pembaruan dilakukan hanya jika cocok dengan sys.version target saat ini; ketidakcocokan di-abort karena error konflik versi (dapat ditangani secara lokal dengan Try/catch). Jika dihilangkan, berlaku last-write-wins tanpa pemeriksaan. Biasanya Anda membaca terlebih dahulu dengan ResourceRead atau ResourcePageRead lalu meneruskan sys.version tersebut (lihat CAS penguncian optimis di Cookbook).
Penulisan berbasis origin
Penulisan selalu tercermin di origin (draft), dan apakah diekspos ke delivery (CDA/ACDA) dikendalikan oleh publish (publish pada ResourceCreate/ResourceUpdate/ResourcePatch, atau ResourcePublish/ResourceUnpublish).
Apa yang dianggap sebagai kegagalan
- Kegagalan sejati adalah error runtime statement: status akhir
Http400 atau lebih (4xx·5xx; bukan kegagalan jikaignoreStatusCode: true) atau timeout, body respons melebihi 10MiB, atau operasi resource yang gagal (target tidak ada, konflik versi, operasi yang tidak didukung, dsb.). Untuk kegagalan semacam ini engine akan meng-abort dan mengompensasi, dan Anda dapat menanganinya secara lokal denganTry/catch/finally. Returnbukanlah error, melainkan penghentian dini yang normal. Ia bukan targetcatch(tidak ada konsep user-throw).- Di dalam
catch, Anda merujuk{ message, statement }melalui/error.
Tanpa agregasi sisi server
Tidak ada operasi server khusus untuk count, sum, atau group-by. Anda menghitungnya dengan mengiterasi ResourcePageRead dan menggunakan SetVar/JsonLogic, sehingga terikat pada ukuran fetch dan maxIterations (tidak cocok untuk mengagregasi jutaan record).
Tanpa penungguan atau penundaan
Script tidak memiliki statement Delay. Script dieksekusi sekali lalu selesai, baik pada jalur permintaan (Sync) maupun di latar belakang (Async), dan tidak menunggu atau melakukan polling secara internal hingga job eksternal selesai (hasil Async bersifat terpisah: pemanggil melakukan polling dengan requestId yang diterima dalam 202 untuk memperoleh nilai Return).
Batasan statis (divalidasi saat disimpan)
Berikut ini diperiksa pada saat Script disimpan (pembuatan/perubahan). Jika dilanggar, penyimpanan ditolak (gagal saat penyusunan, bukan saat runtime).
| Batasan | Default |
|---|---|
Jika ada I/O eksternal, executionMode harus Async | N/A |
Di dalam body Loop, panggilan eksternal Http dan penyerapan file Media dilarang | N/A |
Panggilan eksternal Http maksimum per definisi | 3 (maxExternalIo) |
SetVar maksimum per definisi (termasuk yang bersarang) | 5 (maxSetVar) |
| Total statement maksimum per definisi (termasuk yang bersarang) | 15 (maxStatements) |
Batas atas Http.retry | 2 (maxHttpRetry) |
Batas-batas ini dapat disesuaikan melalui pengaturan server (weegloo.core.script.*) (nilai di atas adalah default).
Penyerapan file Media adalah kapabilitas
MediaIngestdan, tidak seperti panggilan eksternalHttp(ExternalIo), tidak dihitung terhadap batasmaxExternalIo(3). Namun, keharusanAsyncdan larangan bodyLoopditerapkan padanya persis seperti padaHttp.
Anggaran waktu (runtime)
| Mode | Anggaran default |
|---|---|
| Sync | 10 detik (syncTimeoutMs) |
| Async | 60 detik (asyncTimeoutMs) |
Batas jumlah per paket
Script adalah resource Billable, dan jumlah per Organization dibatasi oleh paket.
| Paket | Jumlah Script |
|---|---|
| Free | 3 |
| Basic | 10 |
| Pro | 50 |
| Enterprise | Tak terbatas |
Ketika batas tercapai, pembuatan Script baru ditolak (jalur yang sama dengan resource Billable lainnya).
Model keamanan
Header secret
Item pada Http.headers yang memiliki secret:true bersifat khusus CMA (administrator): nilainya tidak diekspos ke end-user (ServiceUser) dan hanya didekripsi tepat sebelum dikirim. Simpan rahasia seperti kunci API LLM di sini (bahkan saat dipaketkan menjadi App Bundle, nilai secret tetap disamarkan dan tidak pernah keluar dari Space asalnya).
Identitas eksekusi dan otorisasi
- Identitas eksekusi: selama eksekusi, setiap operasi resource dilakukan dengan identitas pengguna yang memanggil
/execute.createdBy/updatedBydari resource yang dibuat atau diubah adalah pemanggil, dan cakupancreatedBy: ":self"juga diuraikan berdasarkan pemanggil. - Ada dua batas otorisasi, dan saat runtime izin resource tidak diperiksa ulang pada setiap statement.
- Saat penyusunan (penyimpanan): ketika sebuah Script disimpan, sistem memeriksa apakah penulis benar-benar memiliki izin resource dan aksi yang dipakai oleh statement-statement di dalamnya. Jika satu saja tidak ada, penyimpanan ditolak (
WGL403015). Dengan kata lain, Script yang memuat operasi tanpa izin memang tidak akan pernah tersimpan sejak awal. - Saat pemanggilan (
/execute): hanya izin Execute Script milik pemanggil yang diperiksa. Tanpa izin itu, hasilnya403. Jika lolos, izin resource per statement tidak diperiksa lagi saat runtime; eksekusi langsung berjalan. Cara kerjanya seperti izin eksekusi fungsi dalam pemrograman. Jika Anda memiliki izin untuk menjalankan fungsi tersebut, izin untuk setiap operasi individual di dalamnya tidak ditanyakan lagi.
- Saat penyusunan (penyimpanan): ketika sebuah Script disimpan, sistem memeriksa apakah penulis benar-benar memiliki izin resource dan aksi yang dipakai oleh statement-statement di dalamnya. Jika satu saja tidak ada, penyimpanan ditolak (
- Cakupan kepemilikan:
createdBy: ":self"pada filterwhereberarti "hanya yang dibuat oleh pemanggil saat ini" (misalnya, hanya membaca dompet milik Anda sendiri). - Izin yang didelegasikan (perhatian bagi penulis): menggabungkan kedua batas di atas, menjalankan sebuah Script setara dengan bertindak dengan izin penulis yang didelegasikan kepadanya. Pemanggil hanya perlu Execute, dan statement di dalam Script berjalan persis dalam cakupan yang diotorisasikan kepada penulis saat disimpan. Akibatnya, operasi resource yang tidak dapat dilakukan sendiri oleh pemanggil pun tetap bisa terjadi melalui Script. Karena izin yang diberikan kepada penulis itulah jangkauan efektif dari Script tersebut, tentukan dengan cermat operasi apa yang Anda masukkan ke dalam Script.
Daftar periksa ringkas
Sebelum menyimpan, periksa hal-hal berikut.
- Jika ada panggilan eksternal (
Http) atau penyerapan file Media,executionModebernilai"Async". - Anda tidak menempatkan panggilan eksternal di dalam body
Loop. - Panggilan eksternal 3 atau kurang,
SetVar5 atau kurang, dan total statement 15 atau kurang. - Nilai secret hanya dimasukkan melalui
secret:truepadaHttp.headers. - Operasi yang tidak dapat dibatalkan (panggilan eksternal) ditempatkan sebisa mungkin di bagian akhir.
- Jika Anda mengkhawatirkan persaingan update/patch, gunakan
versionpadaResourceUpdateatauResourcePatch. - Untuk mengembalikan hasil, Anda menentukan
Return.value.
Dokumen terkait
- Ekspresi nilai: aturan nilai dan kondisi.
- Katalog Statement: field dan hasil dari setiap statement.
- Cookbook: kumpulan contoh yang lengkap.
- Resource dan endpoint Script: struktur resource
Scriptdan endpoint HTTP seperti/execute. - Ikhtisar Script: struktur tingkat atas dan mode eksekusi.
