Permintaan yang Anda buat ke penyimpanan data dapat gagal karena konektivitas yang buruk atau masalah lainnya. Untuk menangani kesalahan dan mengembalikan pesan dengan kode error, bungkus fungsi penyimpanan data dalam pcall().
Panggilan tulis yang gagal, seperti UpdateAsync(), berarti server game tidak menerima respons yang berhasil. Ini tidak selalu menjamin bahwa penulisan backend tidak terjadi. Dalam beberapa skenario kegagalan, kondisi penulisan terakhir mungkin tidak diketahui oleh pemanggil sampai diverifikasi dengan pembacaan tindak lanjut tanpa cache.
Referensi kode kesalahan
| Kode kesalahan | Nama kesalahan | Pesan kesalahan | Catatan | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | Nama kunci tidak boleh kosong. | Periksa apakah input kunci ke fungsi penyimpanan data adalah string kosong. | |
| 102 | KeyNameLimit | Nama kunci melebihi batas 50 karakter. | Periksa apakah input kunci ke fungsi penyimpanan data melebihi panjang 50. | |
| 103 | ValueNotAllowed | Tidak dapat mengizinkan X di DataStore. | Fungsi update yang buruk mengembalikan nilai tipe X. | |
| 104 | CantStoreValue | Tidak dapat menyimpan X di DataStore. | Fungsi pembaruan mengembalikan nilai tipe X yang tidak dapat diserialisasi. | |
| 105 | ValueTooLarge | Nilai yang diserialisasi melebihi batas X. | Jika Anda mengatur nilai dengan SetAsync() atau UpdateAsync(), panjang nilai yang diserialisasi tidak boleh melebihi ukuran X. Untuk memeriksa panjang serialisasi data, gunakan JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue harus berupa integer. | Jika Anda melewatkan nilai maksimum ke GetSortedAsync() untuk OrderedDataStore, itu harus berupa integer. | |
| 106 | MinValueInvalid | MinValue harus berupa integer. | Jika Anda melewatkan nilai minimum ke GetSortedAsync() untuk OrderedDataStore, itu harus berupa integer. | |
| 106 | PageSizeGreater | PageSize harus dalam rentang yang telah ditentukan. | Ukuran halaman minimum untuk OrderedDataStore adalah 1. | |
| 106 | PageSizeLesser | PageSize harus dalam rentang yang telah ditentukan. | Ukuran halaman maksimum untuk OrderedDataStore adalah 100. | |
| 107 | MinMaxOrderInvalid | MaxValue harus lebih besar dari atau sama dengan MinValue. | Nilai maksimum harus lebih besar dari atau sama dengan nilai minimum untuk GetSortedAsync(). | |
| 301 | GetAsyncThrottle | Permintaan GetAsync dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan GetAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 302 | SetAsyncThrottle | Permintaan SetAsync dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan SetAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 303 | IncreAsyncThrottle | Permintaan IncrementAsync dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan IncrementAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 304 | UpdateAsyncThrottle | Permintaan UpdateAsync dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan UpdateAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 304 | TransformThrottle | Permintaan UpdateAsync dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan UpdateAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 305 | GetSortedThrottle | Permintaan GetSorted dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan GetSortedAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 306 | RemoveAsyncThrottle | Permintaan RemoveAsync dibatalkan. Permintaan telah dibatasi tetapi antrean penuh. | Permintaan RemoveAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | |
| 401 | DataModelNoAccess | Permintaan gagal. DataModel tidak dapat diakses saat pengalaman sedang ditutup. | DataModel tidak terinisialisasi karena pengalaman sedang ditutup. | |
| 402 | LuaWebSrvsNoAccess | Permintaan gagal. LuaWebService tidak dapat diakses saat pengalaman sedang ditutup. | LuaWebService tidak terinisialisasi karena pengalaman sedang ditutup. | |
| 403 | StudioAccessToApisNotAllowed | Tidak dapat menulis ke DataStore dari Studio karena akses API tidak diaktifkan. | Akses API harus aktif untuk menggunakan penyimpanan data di Studio. | |
| 404 | InternalError | OrderedDataStore tidak ada. | OrderedDataStore yang terkait dengan permintaan ini tidak ditemukan. Ini mungkin tanda adanya korupsi data. Cobalah lagi nanti. | |
| 501 | InternalError | Tidak dapat mengurai respons karena data mungkin rusak. | Server tidak dapat mengurai respons permintaan Anda. Ini mungkin tanda adanya korupsi data. Cobalah lagi nanti. | |
| 502 | RequestRejected | API Services menolak permintaan dengan error X. | Error X terjadi saat memproses di server Roblox. Cobalah lagi nanti. | |
| 503 | InternalError | Permintaan penyimpanan data berhasil tetapi kunci tidak ditemukan. | Kunci yang diminta tidak ditemukan di penyimpanan data. Ini mungkin tanda adanya korupsi data. Cobalah lagi nanti. | |
| 504 | InternalError | Permintaan penyimpanan data berhasil tetapi respons tidak diformat dengan benar. | Server tidak dapat mengurai respons permintaan Anda. Ini mungkin tanda adanya korupsi data. Cobalah lagi nanti. | |
| 505 | InternalError | Permintaan OrderedDataStore berhasil tetapi respons tidak diformat dengan benar. | Server tidak dapat mengurai respons untuk permintaan OrderedDataStore Anda. Ini mungkin tanda adanya korupsi data. Cobalah lagi nanti. | |
| 509 | OperationNotAllowed | Operasi penyimpanan data diblokir saat dijalankan di RCC Pribadi untuk mencegah kemungkinan korupsi data. | Penulisan penyimpanan data diblokir di saluran RCC pribadi. | |
| 511 | AttributeSizeTooLarge | Ukuran atribut metadata melebihi batas X. | Ukuran metadata yang diserialisasi melebihi batas X. Nilai X bersifat dinamis. Jika ukuran berubah, nilai juga berubah. | |
| 512 | UserIdLimitExceeded | Ukuran UserID melebihi batas X. | Panjang array ID pengguna yang diberikan oleh pengguna melebihi batas X. | |
| 513 | AttributeFormatError | Format atribut userId tidak valid. | ID pengguna yang diberikan bukan angka. | |
| 513 | AttributeFormatError | Format metadata atribut tidak valid. | Metadata bukan tabel. | |
| GetVersionAsyncThrottle | Permintaan GetVersionAsync dibatalkan. Permintaan telah dibatasi. | Permintaan GetVersionAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| GetVersionAtTimeAsyncThrottle | Permintaan GetVersionAtTimeAsync dibatalkan. Permintaan telah dibatasi. | Permintaan GetVersionAtTimeAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| ListDataStoresAsyncThrottle | Permintaan ListDataStoresAsync dibatalkan. Permintaan telah dibatasi. | Permintaan ListDataStoresAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| ListKeysAsyncThrottle | Permintaan ListKeysAsync dibatalkan. Permintaan telah dibatasi. | Permintaan ListKeysAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| ListVersionsAsyncThrottle | Permintaan ListVersionsAsync dibatalkan. Permintaan telah dibatasi. | Permintaan ListVersionsAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| RemoveVersionAsyncThrottle | Permintaan RemoveVersionAsync dibatalkan. Permintaan telah dibatasi. | Permintaan RemoveVersionAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| InvalidTimestamp | Stempel waktu harus positif dan tidak lebih dari sepuluh menit di masa depan. | Stempel waktu yang diberikan kepada GetVersionAtTimeAsync() tidak valid. | ||
| StandardReadExperienceThrottled | Permintaan StandardRead telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), atau pembacaan UpdateAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardRead. | ||
| StandardWriteExperienceThrottled | Permintaan StandardWrite telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardWrite. | ||
| StandardListExperienceThrottled | Permintaan StandardList telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke ListKeysAsync(), ListVersionsAsync(), atau ListDataStoresAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardList. | ||
| StandardRemoveExperienceThrottled | Permintaan StandardRemove telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardRemove. | ||
| OrderedReadExperienceThrottled | Permintaan OrderedRead telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke GetAsync() atau pembacaan UpdateAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedRead. | ||
| OrderedWriteExperienceThrottled | Permintaan OrderedWrite telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedWrite. | ||
| OrderedListExperienceThrottled | Permintaan OrderedList telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke GetSortedAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedList. | ||
| OrderedRemoveExperienceThrottled | Permintaan OrderedRemove telah dibatasi oleh batas pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedRemove. | ||
| StandardReadGameServerThrottled | Permintaan StandardRead telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), atau pembacaan UpdateAsync() pada penyimpanan data standar melebihi batas laju server game StandardRead. | ||
| StandardWriteGameServerThrottled | Permintaan StandardWrite telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data standar melebihi batas laju server game StandardWrite. | ||
| StandardListGameServerThrottled | Permintaan StandardList telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke ListKeysAsync(), ListVersionsAsync(), atau ListDataStoresAsync() pada penyimpanan data standar melebihi batas laju server game StandardList. | ||
| StandardRemoveGameServerThrottled | Permintaan StandardRemove telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data standar melebihi batas laju server game StandardRemove. | ||
| OrderedReadGameServerThrottled | Permintaan OrderedRead telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke GetAsync() atau pembacaan UpdateAsync() pada penyimpanan data terurut melebihi batas laju server game OrderedRead. | ||
| OrderedWriteGameServerThrottled | Permintaan OrderedWrite telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data terurut melebihi batas laju server game OrderedWrite. | ||
| OrderedListGameServerThrottled | Permintaan OrderedList telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke GetSortedAsync() pada penyimpanan data terurut melebihi batas laju server game OrderedList. | ||
| OrderedRemoveGameServerThrottled | Permintaan OrderedRemove telah dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data terurut melebihi batas laju server game OrderedRemove. |
Kode kesalahan server
| Nama kesalahan | Pesan kesalahan | Catatan |
|---|---|---|
| DatastoreDeleted | Penyimpanan data telah dihapus. | Operasi pada penyimpanan data tidak dapat terjadi karena penyimpanan data sebelumnya telah dihapus. |
| DatastoreThrottled | Kecepatan permintaan melebihi maksimum yang diizinkan untuk datastore. | Terlalu banyak permintaan yang dikirim ke satu penyimpanan data. |
| InternalServerError | Terjadi kesalahan server internal. | Kesalahan sesekali pada server Roblox. Cobalah lagi, idealnya dengan penundaan eksponensial. |
| InvalidExclusiveStartKey | Kunci start eksklusif yang diberikan tidak valid. | Kunci start eksklusif (cursor) yang diberikan untuk operasi daftar seperti ListKeysAsync() tidak valid. |
| InvalidPlace | Tempat yang diberikan tidak valid. | Tidak ada ID Universe yang cocok untuk tempat tersebut. Cobalah lagi nanti. |
| InvalidTarget | Target yang diberikan tidak valid. | Nama kunci penyimpanan data terurut melebihi batas 50 karakter. |
| InvalidUniverse | Universe yang diberikan tidak valid. | Tidak ada ID Tempat yang cocok untuk universe tersebut. Cobalah lagi nanti. |
| InvalidUserIds | ID pengguna yang diberikan memiliki format yang tidak valid. | Gagal mengurai ID pengguna. |
| KeyThrottled | Kecepatan permintaan melebihi maksimum yang diizinkan untuk kunci tersebut. | Kecepatan permintaan melebihi batas maksimum yang diizinkan untuk satu kunci. |
| KeyNotFound | Kunci yang diminta tidak ada. | Kunci tidak ada. |
| N/A | Tidak ada halaman untuk dilanjutkan. | Kesalahan ini terjadi ketika Anda memanggil Pages:AdvanceToNextPageAsync() di halaman terakhir. |
| StandardReadExperienceThrottled | Kecepatan permintaan baca standar melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), atau pembacaan UpdateAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardRead. |
| StandardWriteExperienceThrottled | Kecepatan permintaan tulis standar melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardWrite. |
| StandardListExperienceThrottled | Kecepatan permintaan daftar standar melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke ListKeysAsync(), ListVersionsAsync(), atau ListDataStoresAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardList. |
| StandardRemoveExperienceThrottled | Kecepatan permintaan penghapusan standar melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data standar melebihi batas laju pengalaman StandardRemove. |
| OrderedReadExperienceThrottled | Kecepatan permintaan baca terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke GetAsync() atau pembacaan UpdateAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedRead. |
| OrderedWriteExperienceThrottled | Kecepatan permintaan tulis terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedWrite. |
| OrderedListExperienceThrottled | Kecepatan permintaan daftar terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke GetSortedAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedList. |
| OrderedRemoveExperienceThrottled | Kecepatan permintaan penghapusan terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data terurut melebihi batas laju pengalaman OrderedRemove. |
Batas
Model data memiliki batas. Jika sebuah pengalaman melebihi batas ini, layanan secara otomatis membatasi penggunaan penyimpanan data pengalaman tersebut dan menyebabkan permintaan selanjutnya dimasukkan dalam salah satu antrean berikut:
- Set
- Set terurut
- Ambil
- Ambil terurut
Permintaan dalam antrean diproses dalam urutan mereka diterima. Fungsi yang dipanggil terus memblokir selama permintaannya masih dalam antrean. Jika kunci penyimpanan data itu sendiri dibatasi, permintaan ditempatkan dalam antrean tetapi sementara diabaikan.
Setiap antrean memiliki batas 30 permintaan. Ketika batas antrean tercapai, permintaan gagal dengan kode error dalam kisaran 301-306, menunjukkan bahwa permintaan telah sepenuhnya dibatalkan.
Batas akses
Penyimpanan data tunduk pada baik batas tingkat pengalaman dan server. Batas tingkat pengalaman meningkat seiring dengan jumlah pengguna yang bersamaan di seluruh pengalaman, sementara batas tingkat server dapat dikonfigurasi dan dimaksudkan untuk digunakan sebagai alat oleh pencipta.
Batas Pengalaman
Setiap pengalaman diizinkan sejumlah tertentu permintaan penyimpanan data berdasarkan jenis penyimpanan data, jenis permintaan, dan jumlah pengguna bersamaan. Untuk setiap jenis penyimpanan data dan jenis permintaan, batas tersebut dibagi di antara semua fungsi yang terdaftar.
- UpdateAsync() mengkonsumsi dari anggaran permintaan baca dan tulis. Satu panggilan akan mengurangi kedua batas tersebut.
- Server game dan Open Cloud berbagi anggaran; lalu lintas Open Cloud dapat dibatasi oleh penggunaan dalam pengalaman (dan sebaliknya). Lihat Kontrol batas laju untuk panduan lebih lanjut.
Penyimpanan data standar
| Jenis permintaan | API server game | API Open Cloud | Batas bersama (permintaan per menit) |
|---|---|---|---|
| Baca | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Dapatkan Entri Data Store | 300 + concurrentUsers × 40 |
| Tulis | SetAsync() IncrementAsync() UpdateAsync() | Buat, Perbarui, Tambah Entri Data Store | 300 + concurrentUsers × 20 |
| Daftar | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | Daftar Data Store, Daftar Entri Data Store, Daftar Revisi Entri Data Store | 300 + concurrentUsers × 2 |
| Hapus | RemoveAsync() | Hapus Entri Data Store, Hapus Data Store, Kembalikan Data Store | 300 + concurrentUsers × 40 |
Penyimpanan data terurut
| Jenis permintaan | API server game | API Open Cloud | Batas bersama (permintaan per menit) |
|---|---|---|---|
| Baca | GetAsync() UpdateAsync() | Dapatkan Entri Penyimpanan Data Terurut | 300 + concurrentUsers × 40 |
| Tulis | SetAsync() IncrementAsync() UpdateAsync() | Buat, Perbarui, Tambah Entri Penyimpanan Data Terurut | 300 + concurrentUsers × 20 |
| Daftar | GetSortedAsync() | Daftar Entri Penyimpanan Data Terurut | 300 + concurrentUsers × 2 |
| Hapus | RemoveAsync() | Hapus Entri Penyimpanan Data Terurut | 300 + concurrentUsers × 40 |
Kontrol batas laju
Karena permintaan Open Cloud dan server game dibagikan, penting untuk secara independen mengontrol seberapa banyak masing-masing dapat mengkonsumsi dari anggaran.
Server game
Server individu memiliki batas internal, seperti yang dijelaskan di atas. Gunakan kombinasi SetRateLimitForRequestType() dan GetRequestBudgetForRequestType() untuk menjaga kontrol yang lebih tepat atas kontribusi server individu terhadap anggaran total.
Open Cloud
Permintaan Open Cloud memerlukan solusi pembatasan laju eksternal. Kami merekomendasikan salah satu pendekatan berikut:
- (Sederhana) Tambahkan waktu tunggu singkat setelah setiap permintaan, terutama jika memanggil API yang sama dalam loop terus menerus. Atur waktu tunggu ini sama dengan 60 / (penggunaan anggaran yang diinginkan per menit) detik, sebagai batas atas. Perhatikan bahwa pendekatan ini tidak memungkinkan permintaan untuk dikirim dalam lonjakan.
- (Kuat) Implementasikan pembatas laju lokal menggunakan strategi ember bocor.
Kode contoh Node.js berikut mencakup implementasi referensi.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('Variabel lingkungan API_KEY tidak diatur.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventory';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- Konfigurasi pembatasan laju per operasi (permintaan per menit) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// Spacing batas atas per operasi: 60 / (permintaan per menit) detik.
const LIST_INTERVAL_MS = (60 / LIST_RATE_PER_MIN) * 1000;
const GET_INTERVAL_MS = (60 / GET_RATE_PER_MIN) * 1000;
const UPDATE_INTERVAL_MS = (60 / UPDATE_RATE_PER_MIN) * 1000;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// Melakukan permintaan, lalu menunggu interval operasi ini sendiri sebelum mengembalikan.
async function throttledFetch(url, options, intervalMs) {
const response = await fetch(url, options);
await sleep(intervalMs);
return response;
}
async function listEntries(universe, dataStore) {
const listPath = `universes/${universe}/data-stores/${dataStore}/entries`;
const url = baseUrl + listPath;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, LIST_INTERVAL_MS);
return response.json();
}
async function getEntry(path) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, GET_INTERVAL_MS);
return response.json();
}
async function updateEntry(path, payload) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
method: 'PATCH',
headers: {
[apiHeaderKey]: apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) // Badan harus berisi string
}, UPDATE_INTERVAL_MS);
return response;
}
(async () => {
try {
const entries = await listEntries(universeId, dataStoreId);
for (const entry of entries.dataStoreEntries) {
const path = entry.path;
console.log(`\nMemproses entri: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`Status: ${updateResponse.status}`);
console.log(`Respons: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('Terjadi kesalahan selama eksekusi:', error);
}
})();Batas server
Setiap server memiliki batas laju yang dapat dikonfigurasi untuk setiap jenis permintaan, berdasarkan jumlah pemain di server tersebut. Server menerima lonjakan tambahan anggaran permintaan sekali saat pertama kali dibuat. Gunakan GetRequestBudgetForRequestType() untuk mengonfirmasi jumlah permintaan penyimpanan data yang dapat dilakukan server saat ini pada waktu tertentu.
Batas ini dapat dikonfigurasi oleh pencipta menggunakan API SetRateLimitForRequestType(). Menggunakan API ini, seorang pencipta dapat mengonfigurasi batas tarif penyimpanannya sendiri untuk setiap jenis permintaan.
Batas laju default berikut diterapkan jika API tidak dipanggil:
Penyimpanan data standar
| Jenis permintaan | DataStoreRequestType Enum | API server game | Permintaan per menit |
|---|---|---|---|
| Baca | StandardRead | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Tulis | StandardWrite | SetAsync() IncrementAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Daftar | StandardList | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | 5 + numPlayers × 2 |
| Hapus | StandardRemove | RemoveAsync() | 60 + numPlayers × 40 |
| RemoveVersion (Dihapus) | RemoveVersionAsync | RemoveVersionAsync() | 5 + numPlayers × 2 |
Penyimpanan data terurut
| Jenis permintaan | DataStoreRequestType Enum | API server game | Permintaan per menit |
|---|---|---|---|
| Baca | OrderedRead | GetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Tulis | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| Daftar | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| Hapus | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
Batas data
Penyimpanan data membatasi berapa banyak data yang dapat digunakan per entri.
Nama penyimpanan data, nama kunci, dan ruang lingkup harus semuanya dalam panjang karakter tertentu. Gunakan string.len() untuk memeriksa panjangnya.
Data (nilai kunci) juga disimpan sebagai string, terlepas dari jenis aslinya. Anda dapat memeriksa ukuran data dengan fungsi JSONEncode(), yang mengubah data Luau menjadi tabel JSON yang diserialisasi.
| Komponen | Jumlah karakter maksimum |
|---|---|
| Nama penyimpanan data | 50 |
| Nama kunci | 50 |
| Ruang lingkup | 50 |
| Data (nilai kunci) | 4,194,304 per kunci |
Batas metadata
Batas untuk jumlah karakter dalam metadata yang ditentukan pengguna.
| Komponen | Jumlah karakter maksimum |
|---|---|
| Nama kunci | 50 |
| Nilai | 250 |
| Pasangan kunci-nilai | 300 |
Batas throughput
Batas throughput per kunci memastikan bahwa kinerja optimal di server Roblox. Setiap batas berlaku untuk setiap kunci di semua server dalam sebuah pengalaman dan menyegarkan seiring waktu.
Roblox memeriksa penggunaan kuota yang terkait dengan kunci selama 60 detik terakhir. Jika penggunaannya, termasuk permintaan saat ini, berada dalam batas throughput, permintaan disetujui. Jika penggunaannya melebihi batas, permintaan ditolak.
| Jenis permintaan | API server game | API Open Cloud | Batas |
|---|---|---|---|
| Baca | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | Dapatkan Entri Data Store | 25 MB per menit |
| Tulis | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | Buat, Perbarui, Tambah, Hapus Entri Data Store | 4 MB per menit |
Selain batas throughput di atas, Roblox mengatur data ke dalam partisi berdasarkan skema internal. Akibatnya, ketika server backend menerima volume permintaan tinggi ke penyimpanan data yang sama, dapat mengakibatkan pembatasan lebih lanjut. Terlepas dari penyebabnya, pembatasan terwujud sebagai kesalahan DatastoreThrottled atau KeyThrottled, tergantung pada apakah batas throughput dilanggar untuk penyimpanan data tunggal atau untuk kunci. Pesan kesalahan ini berlaku untuk baik penyimpanan data terurut maupun standar.
Batas penyimpanan
Untuk menjaga penyimpanan tetap stabil dan dapat diskalakan, penyimpanan data menggunakan batas tingkat permainan pada penggunaan penyimpanan Anda.
Batas ini terdiri dari alokasi dasar untuk setiap game ditambah alokasi tambahan berdasarkan jumlah pengguna seumur hidup. Pengguna seumur hidup adalah setiap pengguna yang telah bergabung dengan permainan Anda setidaknya sekali.
Batas penyimpanan dihitung menggunakan rumus berikut Total batas penyimpanan versi terbaru = 500 MB + 1 MB × jumlah pengguna seumur hidup.
Penggunaan penyimpanan diukur menggunakan ukuran terkompresi dari versi terbaru setiap kunci. Penyimpanan data secara otomatis mengompres data Anda sebelum penyimpanan, jadi hindari mengompresnya sebelumnya. Prabanding menambah overhead CPU yang tidak perlu dan dapat mengurangi efektivitas kompresi yang terbangun di dalam penyimpanan data. Dengan menyimpan data yang tidak terkompresi, Anda secara otomatis mendapatkan manfaat dari peningkatan algoritma kompresi Roblox dan optimasi berbasis skema di masa depan.
Hanya versi terbaru dari setiap kunci yang dihitung terhadap penggunaan penyimpanan Anda. Kunci yang dihapus dan versi yang digantikan, meskipun masih dapat diakses melalui API versi selama periode retensi mereka, tidak dihitung terhadap penggunaan penyimpanan Anda. Namun, penyimpanan data yang dihapus melalui metode Open Cloud DeleteDataStore terus dihitung terhadap penggunaan penyimpanan selama periode pemrosesan penghapusan 30 hari mereka, sampai mereka dihapus secara permanen.