Permintaan yang Anda buat ke penyimpanan data dapat gagal karena konektivitas yang buruk atau masalah lainnya. Untuk menangani kesalahan dan mengembalikan pesan dengan kode kesalahan, 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, status penulisan akhir mungkin tidak diketahui oleh pemanggil sampai diverifikasi dengan pembacaan lanjutan tanpa cache.
Referensi kode kesalahan
| Kode kesalahan | Nama kesalahan | Pesan kesalahan | Catatan | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | Nama kunci tidak boleh kosong. | Periksa apakah kunci yang dimasukkan ke dalam fungsi penyimpanan data adalah string kosong. | |
| 102 | KeyNameLimit | Nama kunci melebihi batas 50 karakter. | Periksa apakah kunci yang dimasukkan ke dalam fungsi penyimpanan data melebihi panjang 50. | |
| 103 | ValueNotAllowed | Tidak dapat mengizinkan X dalam DataStore. | Fungsi pembaruan yang buruk mengembalikan nilai dari tipe X. | |
| 104 | CantStoreValue | Tidak dapat menyimpan X dalam DataStore. | Fungsi pembaruan mengembalikan nilai dari tipe X yang tidak dapat diserialisasi. | |
| 105 | ValueTooLarge | Nilai yang diserialisasi melebihi batas X. | Jika Anda mengatur nilai dengan SetAsync() atau UpdateAsync(), panjang yang diserialisasi dari nilai tidak boleh melebihi ukuran X. Untuk memeriksa panjang yang diserialisasi dari data, gunakan JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue harus berupa integer. | Jika Anda mengirimkan nilai maksimum ke GetSortedAsync() untuk OrderedDataStore, itu harus berupa integer. | |
| 106 | MinValueInvalid | MinValue harus berupa integer. | Jika Anda mengirimkan nilai minimum ke GetSortedAsync() untuk OrderedDataStore, itu harus berupa integer. | |
| 106 | PageSizeGreater | PageSize harus berada dalam rentang yang telah ditentukan. | Ukuran halaman minimum untuk OrderedDataStore adalah 1. | |
| 106 | PageSizeLesser | PageSize harus berada 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 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 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 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 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 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 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 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 dimatikan. | DataModel tidak diinisialisasi karena pengalaman sedang dimatikan. | |
| 402 | LuaWebSrvsNoAccess | Permintaan gagal. LuaWebService tidak dapat diakses saat pengalaman sedang dimatikan. | LuaWebService tidak diinisialisasi karena pengalaman sedang dimatikan. | |
| 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 kerusakan data. Coba lagi nanti. | |
| 501 | InternalError | Tidak dapat mengurai respons karena data mungkin rusak. | Server tidak dapat mengurai respons untuk permintaan Anda. Ini mungkin tanda kerusakan data. Coba lagi nanti. | |
| 502 | RequestRejected | Layanan API menolak permintaan dengan kesalahan X. | Kesalahan X terjadi saat memproses di server Roblox. Coba lagi nanti. | |
| 503 | InternalError | Permintaan penyimpanan data berhasil tetapi kunci tidak ditemukan. | Kunci yang diminta tidak ditemukan di penyimpanan data. Ini mungkin tanda kerusakan data. Coba lagi nanti. | |
| 504 | InternalError | Permintaan penyimpanan data berhasil tetapi respons tidak diformat dengan benar. | Server tidak dapat mengurai respons untuk permintaan Anda. Ini mungkin tanda kerusakan data. Coba 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 kerusakan data. Coba lagi nanti. | |
| 509 | OperationNotAllowed | Operasi penyimpanan data diblokir saat berjalan di RCC Pribadi untuk mencegah kemungkinan kerusakan data. | Tulisan 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 dibatasi. | Permintaan GetVersionAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| GetVersionAtTimeAsyncThrottle | Permintaan GetVersionAtTimeAsync dibatalkan. Permintaan dibatasi. | Permintaan GetVersionAtTimeAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| ListDataStoresAsyncThrottle | Permintaan ListDataStoresAsync dibatalkan. Permintaan dibatasi. | Permintaan ListDataStoresAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| ListKeysAsyncThrottle | Permintaan ListKeysAsync dibatalkan. Permintaan dibatasi. | Permintaan ListKeysAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| ListVersionsAsyncThrottle | Permintaan ListVersionsAsync dibatalkan. Permintaan dibatasi. | Permintaan ListVersionsAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| RemoveVersionAsyncThrottle | Permintaan RemoveVersionAsync dibatalkan. Permintaan dibatasi. | Permintaan RemoveVersionAsync() telah melebihi ukuran antrean maksimum dan Roblox tidak dapat memproses permintaan pada throughput saat ini. | ||
| InvalidTimestamp | Timestamp harus positif dan tidak lebih dari sepuluh menit di masa depan. | Timestamp yang diberikan ke GetVersionAtTimeAsync() tidak valid. | ||
| StandardReadExperienceThrottled | Permintaan StandardRead dibatasi oleh batas pengalaman. | Sebuah permintaan ke GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), atau pembacaan UpdateAsync() pada penyimpanan data standar melebihi batas tingkat pengalaman StandardRead. | ||
| StandardWriteExperienceThrottled | Permintaan StandardWrite dibatasi oleh batas pengalaman. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data standar melebihi batas tingkat pengalaman StandardWrite. | ||
| StandardListExperienceThrottled | Permintaan StandardList dibatasi oleh batas pengalaman. | Sebuah permintaan ke ListKeysAsync(), ListVersionsAsync(), atau ListDataStoresAsync() pada penyimpanan data standar melebihi batas tingkat pengalaman StandardList. | ||
| StandardRemoveExperienceThrottled | Permintaan StandardRemove dibatasi oleh batas pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data standar melebihi batas tingkat pengalaman StandardRemove. | ||
| OrderedReadExperienceThrottled | Permintaan OrderedRead dibatasi oleh batas pengalaman. | Sebuah permintaan ke GetAsync(), BatchGetAsync(), atau pembacaan UpdateAsync() pada penyimpanan data terurut melebihi batas tingkat pengalaman OrderedRead. | ||
| OrderedWriteExperienceThrottled | Permintaan OrderedWrite dibatasi oleh batas pengalaman. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data terurut melebihi batas tingkat pengalaman OrderedWrite. | ||
| OrderedListExperienceThrottled | Permintaan OrderedList dibatasi oleh batas pengalaman. | Sebuah permintaan ke GetSortedAsync() pada penyimpanan data terurut melebihi batas tingkat pengalaman OrderedList. | ||
| OrderedRemoveExperienceThrottled | Permintaan OrderedRemove dibatasi oleh batas pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data terurut melebihi batas tingkat pengalaman OrderedRemove. | ||
| StandardReadGameServerThrottled | Permintaan StandardRead dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), atau pembacaan UpdateAsync() pada penyimpanan data standar melebihi batas tingkat server game StandardRead. | ||
| StandardWriteGameServerThrottled | Permintaan StandardWrite dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data standar melebihi batas tingkat server game StandardWrite. | ||
| StandardListGameServerThrottled | Permintaan StandardList dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke ListKeysAsync(), ListVersionsAsync(), atau ListDataStoresAsync() pada penyimpanan data standar melebihi batas tingkat server game StandardList. | ||
| StandardRemoveGameServerThrottled | Permintaan StandardRemove dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data standar melebihi batas tingkat server game StandardRemove. | ||
| OrderedReadGameServerThrottled | Permintaan OrderedRead dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke GetAsync(), BatchGetAsync(), atau pembacaan UpdateAsync() pada penyimpanan data terurut melebihi batas tingkat server game OrderedRead. | ||
| OrderedWriteGameServerThrottled | Permintaan OrderedWrite dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke SetAsync(), IncrementAsync(), atau penulisan UpdateAsync() pada penyimpanan data terurut melebihi batas tingkat server game OrderedWrite. | ||
| OrderedListGameServerThrottled | Permintaan OrderedList dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke GetSortedAsync() pada penyimpanan data terurut melebihi batas tingkat server game OrderedList. | ||
| OrderedRemoveGameServerThrottled | Permintaan OrderedRemove dibatasi oleh batas server game atau antrean permintaan penuh. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data terurut melebihi batas tingkat server game OrderedRemove. |
Kode kesalahan server
| Nama kesalahan | Pesan kesalahan | Catatan |
|---|---|---|
| DatastoreDeleted | Penyimpanan data telah dihapus. | Sebuah 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 di server Roblox. Coba lagi, idealnya dengan penundaan eksponensial. |
| InvalidExclusiveStartKey | Kunci awal eksklusif yang diberikan tidak valid. | Kunci awal eksklusif (kursor) yang diberikan untuk operasi daftar seperti ListKeysAsync() tidak valid. |
| InvalidPlace | Tempat yang diberikan tidak valid. | Tidak ada ID Universe yang cocok untuk tempat tersebut. Coba 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. Coba 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 kecepatan permintaan 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() pada 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 tingkat 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 tingkat 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 tingkat pengalaman StandardList. |
| StandardRemoveExperienceThrottled | Kecepatan permintaan hapus standar melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data standar melebihi batas tingkat pengalaman StandardRemove. |
| OrderedReadExperienceThrottled | Kecepatan permintaan baca terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke GetAsync(), BatchGetAsync(), atau pembacaan UpdateAsync() pada penyimpanan data terurut melebihi batas tingkat 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 tingkat pengalaman OrderedWrite. |
| OrderedListExperienceThrottled | Kecepatan permintaan daftar terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke GetSortedAsync() pada penyimpanan data terurut melebihi batas tingkat pengalaman OrderedList. |
| OrderedRemoveExperienceThrottled | Kecepatan permintaan hapus terurut melebihi maksimum yang diizinkan untuk pengalaman. | Sebuah permintaan ke RemoveAsync() pada penyimpanan data terurut melebihi batas tingkat pengalaman OrderedRemove. |
Batasan
Model data memiliki batasan. Jika sebuah pengalaman melebihi batasan ini, layanan secara otomatis membatasi penggunaan penyimpanan data pengalaman tersebut dan menyebabkan permintaan di masa depan ditempatkan dalam salah satu antrean berikut:
- Set
- Set terurut
- Ambil
- Ambil terurut
Permintaan dalam antrean ditangani sesuai urutan penerimaannya. Fungsi yang dipanggil terus menunggu selama permintaannya masih dalam antrean. Jika kunci penyimpanan data itu sendiri dibatasi, permintaan ditempatkan dalam antrean tetapi sementara dilewati.
Setiap antrean memiliki batas 30 permintaan. Ketika batas antrean tercapai, permintaan gagal dengan kode kesalahan dalam rentang 301-306, menunjukkan bahwa permintaan telah dibatalkan sepenuhnya.
Batasan akses
Penyimpanan data tunduk pada batasan tingkat pengalaman dan server. Batasan tingkat pengalaman skala dengan total pengguna bersamaan di seluruh pengalaman, sementara batasan tingkat server dapat dikonfigurasi dan dimaksudkan untuk digunakan sebagai alat oleh pencipta.
Batasan Pengalaman
Setiap pengalaman diizinkan sejumlah permintaan penyimpanan data tertentu berdasarkan jenis penyimpanan data, jenis permintaan, dan jumlah pengguna bersamaan. Untuk setiap jenis penyimpanan data dan jenis permintaan, batasan dibagi di antara semua fungsi yang terdaftar.
- UpdateAsync() mengkonsumsi dari anggaran permintaan baca dan tulis. Satu panggilan akan mengurangi kedua batasan.
- Server game dan Open Cloud berbagi anggaran; lalu lintas Open Cloud dapat dibatasi oleh penggunaan dalam pengalaman (dan sebaliknya). Lihat Kontrol batasan laju untuk panduan lebih lanjut.
Penyimpanan data standar
| Jenis permintaan | API server game | API Open Cloud | Batasan bersama (permintaan per menit) |
|---|---|---|---|
| Baca | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Ambil Entri Penyimpanan Data | 300 + pengguna bersamaan × 40 |
| Tulis | SetAsync() IncrementAsync() UpdateAsync() | Buat, Perbarui, Tambah Entri Penyimpanan Data | 300 + pengguna bersamaan × 20 |
| Daftar | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | Daftar Penyimpanan Data, Daftar Entri Penyimpanan Data, Daftar Revisi Entri Penyimpanan Data | 300 + pengguna bersamaan × 2 |
| Hapus | RemoveAsync() | Hapus Entri Penyimpanan Data, Hapus Penyimpanan Data, Pulihkan Penyimpanan Data | 300 + pengguna bersamaan × 40 |
Penyimpanan data terurut
| Jenis permintaan | API server game | API Open Cloud | Batasan bersama (permintaan per menit) |
|---|---|---|---|
| Baca | GetAsync() BatchGetAsync() UpdateAsync() | Ambil Entri Penyimpanan Data Terurut | 300 + pengguna bersamaan × 40 |
| Tulis | SetAsync() IncrementAsync() UpdateAsync() | Buat, Perbarui, Tambah Entri Penyimpanan Data Terurut | 300 + pengguna bersamaan × 20 |
| Daftar | GetSortedAsync() | Daftar Entri Penyimpanan Data Terurut | 300 + pengguna bersamaan × 2 |
| Hapus | RemoveAsync() | Hapus Entri Penyimpanan Data Terurut | 300 + pengguna bersamaan × 40 |
Kontrol batasan laju
Karena permintaan Open Cloud dan server game dibagikan, penting untuk mengontrol secara independen seberapa banyak masing-masing dapat mengkonsumsi dari anggaran.
Server game
Server individu memiliki batasan bawaan, seperti yang dijelaskan di atas. Gunakan kombinasi SetRateLimitForRequestType() dan GetRequestBudgetForRequestType() untuk mempertahankan kontrol yang lebih halus atas kontribusi server individu terhadap total anggaran.
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 berkelanjutan. Atur waktu tunggu ini sama dengan 60 / (konsumsi anggaran yang diinginkan per menit) detik, sebagai batas atas. Perhatikan bahwa pendekatan ini tidak memungkinkan permintaan dikirim dalam lonjakan.
- (Kuat) Implementasikan pembatas laju lokal menggunakan strategi ember bocor.
Contoh kode Node.js berikut mencakup implementasi referensi.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('Variabel lingkungan API_KEY tidak disetel.');
}
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;
// Spasi 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, kemudian menunggu interval operasi ini sendiri sebelum kembali.
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 berupa 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);
}
})();Batasan server
Setiap server memiliki batasan laju yang dapat dikonfigurasi untuk setiap jenis permintaan, berdasarkan jumlah pemain di server tersebut. Server menerima lonjakan anggaran permintaan tambahan satu kali saat pertama kali dibuat. Gunakan GetRequestBudgetForRequestType() untuk mengonfirmasi jumlah permintaan penyimpanan data yang dapat dilakukan server saat ini pada waktu tertentu.
Batasan ini dapat dikonfigurasi oleh pencipta menggunakan API SetRateLimitForRequestType(). Menggunakan API ini, seorang pencipta dapat mengonfigurasi batasan laju penyimpanan data mereka sendiri untuk setiap jenis permintaan.
Batasan default berikut berlaku 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() BatchGetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Tulis | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| Daftar | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| Hapus | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
Batasan data
Penyimpanan data membatasi seberapa banyak data yang dapat digunakan per entri.
Nama penyimpanan data, nama kunci, dan ruang lingkup semuanya harus berada di bawah panjang karakter tertentu. Gunakan string.len() untuk memeriksa panjangnya.
Data (nilai kunci) juga disimpan sebagai string, terlepas dari tipe awalnya. Anda dapat memeriksa ukuran data dengan fungsi JSONEncode(), yang mengonversi 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 |
Batasan metadata
Batasan jumlah karakter dalam metadata yang ditentukan pengguna.
| Komponen | Jumlah karakter maksimum |
|---|---|
| Nama kunci | 50 |
| Nilai | 250 |
| Pasangan kunci-nilai | 300 |
Batasan throughput
Batasan throughput per kunci memastikan bahwa kinerja optimal di server Roblox. Setiap batasan berlaku untuk setiap kunci tunggal di semua server dalam sebuah pengalaman dan menyegarkan seiring waktu.
Roblox memeriksa penggunaan kuota yang terkait dengan kunci selama 60 detik terakhir. Jika penggunaan, termasuk permintaan saat ini, berada dalam batas throughput, permintaan disetujui. Jika penggunaan melebihi batas, permintaan ditolak.
| Jenis permintaan | API server game | API Open Cloud | Batas |
|---|---|---|---|
| Baca | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | Ambil Entri Penyimpanan Data | 25 MB per menit |
| Tulis | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | Buat, Perbarui, Tambah, Hapus Entri Penyimpanan Data | 4 MB per menit |
Selain batasan throughput di atas, Roblox mengorganisir data ke dalam partisi berdasarkan skema internal. Akibatnya, ketika server backend menerima volume permintaan yang tinggi untuk penyimpanan data yang sama, ini dapat mengakibatkan pembatasan lebih lanjut. Terlepas dari penyebabnya, pembatasan muncul sebagai kesalahan DatastoreThrottled atau KeyThrottled, tergantung pada apakah batas throughput terlampaui untuk satu penyimpanan data atau kunci. Pesan kesalahan ini berlaku untuk penyimpanan data terurut dan standar.
Batasan penyimpanan
Untuk menjaga penyimpanan tetap stabil dan dapat diskalakan, penyimpanan data menggunakan batasan tingkat permainan pada penggunaan penyimpanan Anda.
Batasan ini terdiri dari alokasi dasar untuk setiap permainan ditambah alokasi tambahan berdasarkan jumlah pengguna seumur hidup. Pengguna seumur hidup adalah pengguna yang telah bergabung dengan permainan Anda setidaknya sekali.
Batasan 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 sendiri. Pra-kompresi menambah overhead CPU yang tidak perlu dan dapat mengurangi efektivitas kompresi bawaan penyimpanan data. Dengan menyimpan data yang tidak terkompresi, Anda secara otomatis mendapatkan manfaat dari perbaikan 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.