يمكن أن تفشل الطلبات التي تقوم بها إلى تخزين البيانات بسبب اتصال ضعيف أو مشاكل أخرى. لمعالجة الأخطاء وإرجاع رسائل مع رمز خطأ، قم بلف وظائف تخزين البيانات في pcall().
تعني مكالمة الكتابة الفاشلة، مثل UpdateAsync(), أن خادم اللعبة لم يتلق استجابة ناجحة. لا يضمن دائمًا أن الكتابة في الخلفية لم تحدث. في بعض سيناريوهات الفشل، قد تكون حالة الكتابة النهائية غير معروفة للمتصل حتى يتم التحقق منها بقراءة لاحقة بدون ذاكرة تخزين مؤقت.
مرجع رموز الخطأ
| رمز الخطأ | اسم الخطأ | رسالة الخطأ | ملاحظات | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | لا يمكن أن يكون اسم المفتاح فارغًا. | تحقق مما إذا كانت قيمة المفتاح المدخلة في وظيفة تخزين البيانات هي سلسلة فارغة. | |
| 102 | KeyNameLimit | يتجاوز اسم المفتاح الحد المكون من 50 حرفًا. | تحقق إذا كانت قيمة المفتاح المدخلة في وظيفة تخزين البيانات تتجاوز طول 50. | |
| 103 | ValueNotAllowed | لا يمكن السماح بـ X في DataStore. | أعاد دالة التحديث المعطلة قيمة من النوع X. | |
| 104 | CantStoreValue | لا يمكن تخزين X في DataStore. | أعادت دالة التحديث قيمة من النوع X لم يتم تسلسلها. | |
| 105 | ValueTooLarge | يتجاوز القيمة المتسلسلة حد X. | إذا كنت تقوم بتعيين قيمة باستخدام SetAsync() أو UpdateAsync()، لا يمكن أن يتجاوز الطول المتسلسل للقيمة الحجم X. للتحقق من الطول المتسلسل للبيانات، استخدم JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue يجب أن يكون عددًا صحيحًا. | إذا كنت تمرر قيمة قصوى إلى GetSortedAsync() لـ OrderedDataStore، يجب أن يكون عددًا صحيحًا. | |
| 106 | MinValueInvalid | MinValue يجب أن يكون عددًا صحيحًا. | إذا كنت تمرر قيمة دنيا إلى GetSortedAsync() لـ OrderedDataStore، يجب أن يكون عددًا صحيحًا. | |
| 106 | PageSizeGreater | PageSize يجب أن يكون ضمن نطاق محدد مسبقًا. | أقل حجم للصفحة لـ OrderedDataStore هو 1. | |
| 106 | PageSizeLesser | PageSize يجب أن يكون ضمن نطاق محدد مسبقًا. | أقصى حجم للصفحة لـ OrderedDataStore هو 100. | |
| 107 | MinMaxOrderInvalid | يجب أن تكون MaxValue أكبر من أو تساوي MinValue. | يجب أن تكون القيمة القصوى أكبر من أو تساوي القيمة الدنيا لـ GetSortedAsync(). | |
| 301 | GetAsyncThrottle | تم إسقاط طلب GetAsync. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب GetAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 302 | SetAsyncThrottle | تم إسقاط طلب SetAsync. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب SetAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 303 | IncreAsyncThrottle | تم إسقاط طلب IncrementAsync. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب IncrementAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 304 | UpdateAsyncThrottle | تم إسقاط طلب UpdateAsync. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب UpdateAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 304 | TransformThrottle | تم إسقاط طلب UpdateAsync. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب UpdateAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 305 | GetSortedThrottle | تم إسقاط طلب GetSorted. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب GetSortedAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 306 | RemoveAsyncThrottle | تم إسقاط طلب RemoveAsync. تم تقييد الطلب ولكن كانت قائمة الانتظار ممتلئة. | تجاوز طلب RemoveAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | |
| 401 | DataModelNoAccess | فشل الطلب. DataModel غير قابل للوصول أثناء إغلاق التجربة. | لم يتم تهيئة DataModel لأن التجربة تغلق. | |
| 402 | LuaWebSrvsNoAccess | فشل الطلب. LuaWebService غير قابل للوصول أثناء إغلاق التجربة. | لم يتم تهيئة LuaWebService لأن التجربة تغلق. | |
| 403 | StudioAccessToApisNotAllowed | لا يمكن الكتابة إلى DataStore من الاستوديو لأن الوصول إلى واجهة البرمجة غير مفعل. | يجب تفعيل الوصول إلى واجهة البرمجة لاستخدام تخزين البيانات في الاستوديو. | |
| 404 | InternalError | لا يوجد OrderedDataStore. | لم يتم العثور على OrderedDataStore المرتبط بهذا الطلب. قد تكون هذه علامة على تلف البيانات. حاول مرة أخرى لاحقًا. | |
| 501 | InternalError | لا يمكن تحليل الاستجابة لأن البيانات قد تكون تالفة. | لم يكن الخادم قادرًا على تحليل الاستجابة لطلبك. قد تكون هذه علامة على تلف البيانات. حاول مرة أخرى لاحقًا. | |
| 502 | RequestRejected | رفضت خدمات API الطلب بالخطأ X. | حدث خطأ X عند المعالجة على خوادم Roblox. حاول مرة أخرى لاحقًا. | |
| 503 | InternalError | كان طلب تخزين البيانات ناجحًا ولكن المفتاح لم يُعثر عليه. | لم يُعثر على المفتاح المطلوب في تخزين البيانات. قد تكون هذه علامة على تلف البيانات. حاول مرة أخرى لاحقًا. | |
| 504 | InternalError | كان طلب تخزين البيانات ناجحًا ولكن الاستجابة لم تُنسق بشكل صحيح. | لم يكن الخادم قادرًا على تحليل الاستجابة لطلبك. قد تكون هذه علامة على تلف البيانات. حاول مرة أخرى لاحقًا. | |
| 505 | InternalError | كان طلب OrderedDataStore ناجحًا ولكن الاستجابة لم تُنسق بشكل صحيح. | لم يكن الخادم قادرًا على تحليل الاستجابة لطلبك لـ OrderedDataStore. قد تكون هذه علامة على تلف البيانات. حاول مرة أخرى لاحقًا. | |
| 509 | OperationNotAllowed | تم حظر عمليات تخزين البيانات أثناء التشغيل على مكتب شخصي RCC لمنع تلف البيانات المحتمل. | تُحظر كتابات تخزين البيانات على قنوات RCC خاصة. | |
| 511 | AttributeSizeTooLarge | يتجاوز حجم خاصية البيانات الوصفية الحد X. | يتجاوز حجم البيانات الوصفية المتسلسل الحد X. القيمة X ديناميكية. إذا تغير الحجم، تتغير القيمة أيضًا. | |
| 512 | UserIdLimitExceeded | يتجاوز حجم UserID الحد X. | يتجاوز طول مصفوفة معرفات المستخدم التي قدمها المستخدم الحد X. | |
| 513 | AttributeFormatError | تنسيق خاصية userId غير صالح. | لم يكن معرف المستخدم المقدم رقمًا. | |
| 513 | AttributeFormatError | تنسيق البيانات الوصفية للخاصية غير صالح. | لم تكن البيانات الوصفية جدولاً. | |
| GetVersionAsyncThrottle | تم إسقاط طلب GetVersionAsync. تم تقييد الطلب. | تجاوز طلب GetVersionAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | ||
| GetVersionAtTimeAsyncThrottle | تم إسقاط طلب GetVersionAtTimeAsync. تم تقييد الطلب. | تجاوز طلب GetVersionAtTimeAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | ||
| ListDataStoresAsyncThrottle | تم إسقاط طلب ListDataStoresAsync. تم تقييد الطلب. | تجاوز طلب ListDataStoresAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | ||
| ListKeysAsyncThrottle | تم إسقاط طلب ListKeysAsync. تم تقييد الطلب. | تجاوز طلب ListKeysAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | ||
| ListVersionsAsyncThrottle | تم إسقاط طلب ListVersionsAsync. تم تقييد الطلب. | تجاوز طلب ListVersionsAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | ||
| RemoveVersionAsyncThrottle | تم إسقاط طلب RemoveVersionAsync. تم تقييد الطلب. | تجاوز طلب RemoveVersionAsync() الحد الأقصى لحجم قائمة الانتظار ولا يمكن أن تعالج Roblox الطلبات عند معدل الإنتاج الحالي. | ||
| InvalidTimestamp | يجب أن يكون الطابع الزمني إيجابيًا وألا يزيد عن عشر دقائق في المستقبل. | لم يكن الطابع الزمني المدخل لـ GetVersionAtTimeAsync() صالحًا. | ||
| StandardReadExperienceThrottled | تم تقييد طلب StandardRead بواسطة حدود التجربة. | تجاوز طلب إلى GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), أو قراءة UpdateAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل تجربة StandardRead. | ||
| StandardWriteExperienceThrottled | تم تقييد طلب StandardWrite بواسطة حدود التجربة. | تجاوز طلب إلى SetAsync(), IncrementAsync(), أو كتابة UpdateAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل تجربة StandardWrite. | ||
| StandardListExperienceThrottled | تم تقييد طلب StandardList بواسطة حدود التجربة. | تجاوز طلب إلى ListKeysAsync(), ListVersionsAsync(), أو ListDataStoresAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل تجربة StandardList. | ||
| StandardRemoveExperienceThrottled | تم تقييد طلب StandardRemove بواسطة حدود التجربة. | تجاوز طلب إلى RemoveAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل تجربة StandardRemove. | ||
| OrderedReadExperienceThrottled | تم تقييد طلب OrderedRead بواسطة حدود التجربة. | تجاوز طلب إلى GetAsync() أو قراءة UpdateAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة OrderedRead. | ||
| OrderedWriteExperienceThrottled | تم تقييد طلب OrderedWrite بواسطة حدود التجربة. | تجاوز طلب إلى SetAsync(), IncrementAsync(), أو كتابة UpdateAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة OrderedWrite. | ||
| OrderedListExperienceThrottled | تم تقييد طلب OrderedList بواسطة حدود التجربة. | تجاوز طلب إلى GetSortedAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة OrderedList. | ||
| OrderedRemoveExperienceThrottled | تم تقييد طلب OrderedRemove بواسطة حدود التجربة. | تجاوز طلب إلى RemoveAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة OrderedRemove. | ||
| StandardReadGameServerThrottled | تم تقييد طلب StandardRead بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), أو قراءة UpdateAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل خادم اللعبة StandardRead. | ||
| StandardWriteGameServerThrottled | تم تقييد طلب StandardWrite بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى SetAsync(), IncrementAsync(), أو كتابة UpdateAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل خادم اللعبة StandardWrite. | ||
| StandardListGameServerThrottled | تم تقييد طلب StandardList بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى ListKeysAsync(), ListVersionsAsync(), أو ListDataStoresAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل خادم اللعبة StandardList. | ||
| StandardRemoveGameServerThrottled | تم تقييد طلب StandardRemove بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى RemoveAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل خادم اللعبة StandardRemove. | ||
| OrderedReadGameServerThrottled | تم تقييد طلب OrderedRead بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى GetAsync() أو قراءة UpdateAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل خادم اللعبة OrderedRead. | ||
| OrderedWriteGameServerThrottled | تم تقييد طلب OrderedWrite بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى SetAsync(), IncrementAsync(), أو كتابة UpdateAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل خادم اللعبة OrderedWrite. | ||
| OrderedListGameServerThrottled | تم تقييد طلب OrderedList بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى GetSortedAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل خادم اللعبة OrderedList. | ||
| OrderedRemoveGameServerThrottled | تم تقييد طلب OrderedRemove بواسطة حدود خادم اللعبة أو كانت قائمة الانتظار ممتلئة. | تجاوز طلب إلى RemoveAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل خادم اللعبة OrderedRemove. |
رموز أخطاء الخادم
| اسم الخطأ | رسالة الخطأ | ملاحظات |
|---|---|---|
| DatastoreDeleted | تم حذف تخزين البيانات. | لا يمكن حدوث عملية على تخزين البيانات لأن تخزين البيانات تم حذفه سابقًا. |
| DatastoreThrottled | يتجاوز معدل الطلب الحد الأقصى المسموح به لـ datastore. | تم إرسال الكثير من الطلبات إلى تخزين بيانات واحد. |
| InternalServerError | حدث خطأ داخلي في الخادم. | خطأ عرضي على خوادم Roblox. حاول مرة أخرى، من الأفضل مع تأخير متزايد. |
| InvalidExclusiveStartKey | المفتاح الأول الحصري المدخل غير صالح. | المفتاح الأول الحصري (المؤشر) المدخل إلى عملية قائمة مثل ListKeysAsync() غير صالح. |
| InvalidPlace | المكان المدخل غير صالح. | لا يوجد معرف كون متطابق للمكان. حاول مرة أخرى لاحقًا. |
| InvalidTarget | الهدف المدخل غير صالح. | يتجاوز اسم مفتاح تخزين البيانات المرتبة حد الـ 50 حرفًا. |
| InvalidUniverse | الكون المدخل غير صالح. | لا يوجد معرف مكان متطابق للكون. حاول مرة أخرى لاحقًا. |
| InvalidUserIds | معرفات المستخدم المدخلة لها تنسيق غير صالح. | فشل تحليل معرفات المستخدم. |
| KeyThrottled | يتجاوز معدل الطلب الحد الأقصى المسموح به للمفتاح. | يتجاوز معدل الطلب الحد الأقصى المسموح به للطلبات لمفتاح واحد فقط. |
| KeyNotFound | المفتاح المطلوب لا يوجد. | المفتاح غير موجود. |
| N/A | لا توجد صفحات للتقدم إليها. | يحدث هذا الخطأ عندما تقوم باستدعاء Pages:AdvanceToNextPageAsync() على الصفحة الأخيرة. |
| StandardReadExperienceThrottled | يتجاوز معدل طلب القراءة القياسي الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), أو قراءة UpdateAsync() على تخزين البيانات القياسي الحد الأقصى لمعدل تجربة القراءة القياسية. |
| StandardWriteExperienceThrottled | يتجاوز معدل طلب الكتابة القياسي الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى SetAsync(), IncrementAsync(), أو كتابة UpdateAsync() على تخزين البيانات القياسي الحد الأقصى لمعدل تجربة الكتابة القياسية. |
| StandardListExperienceThrottled | يتجاوز معدل طلب القائمة القياسي الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى ListKeysAsync(), ListVersionsAsync(), أو ListDataStoresAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل تجربة القائمة القياسية. |
| StandardRemoveExperienceThrottled | يتجاوز معدل طلب الإزالة القياسي الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى RemoveAsync() على تخزين بيانات قياسي الحد الأقصى لمعدل تجربة الإزالة القياسية. |
| OrderedReadExperienceThrottled | يتجاوز معدل طلب القراءة المرتبة الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى GetAsync() أو قراءة UpdateAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة القراءة المرتبة. |
| OrderedWriteExperienceThrottled | يتجاوز معدل طلب الكتابة المرتبة الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى SetAsync(), IncrementAsync(), أو كتابة UpdateAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة الكتابة المرتبة. |
| OrderedListExperienceThrottled | يتجاوز معدل طلب القائمة المرتبة الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى GetSortedAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة القائمة المرتبة. |
| OrderedRemoveExperienceThrottled | يتجاوز معدل طلب الإزالة المرتبة الحد الأقصى المسموح به للتجربة. | تجاوز طلب إلى RemoveAsync() على تخزين بيانات مرتب بنمط أعلى من الحد الأقصى لمعدل تجربة الإزالة المرتبة. |
الحدود
تمتلك نماذج البيانات حدودًا. إذا تجاوزت تجربة هذه الحدود، تقوم الخدمة تلقائيًا بتقييد استخدام تخزين البيانات للتجربة وتسبب وضع الطلبات المستقبلية في واحدة من قوائم الانتظار التالية:
- تعيين
- تعيين مرتب
- الحصول
- الحصول المرتب
تتم معالجة الطلبات في قائمة الانتظار بالترتيب الذي تم استلامها فيه. تستمر الوظيفة المستدعاة في التخلي عن الطلب طالما أن طلبها لا يزال في قائمة الانتظار. إذا كان مفتاح تخزين البيانات نفسه مقيدًا، يتم وضع الطلب في قائمة الانتظار ولكن يتم تخطيه مؤقتًا.
تحتوي كل قائمة انتظار على حد 30 طلبًا. عند الوصول إلى حد قائمة الانتظار، تفشل الطلبات مع رمز خطأ في نطاق 301-306، مما يدل على أنه تم إسقاط الطلبات بالكامل.
حدود الوصول
تخزين البيانات خاضع لكل من حدود التجربة والحدود على مستوى الخادم.scale حدود مستوى التجربة تتوسع مع إجمالي المستخدمين المتزامنين عبر التجربة، بينما تم تكوين حدود مستوى الخادم لتستخدم كأداة من قبل المنشئ.
حدود التجربة
يسمح لكل تجربة بعدد معين من طلبات تخزين البيانات بناءً على نوع تخزين البيانات، ونوع الطلب، وعدد المستخدمين المتزامنين. بالنسبة لكل نوع من أنواع تخزين البيانات ونوع الطلب، يتم مشاركة الحد بين جميع الوظائف المذكورة.
- تستهلك UpdateAsync() من كل من ميزانية طلب القراءة والكتابة. ستقوم مكالمة واحدة بتقليل كلا الحدين.
- يشارك خادم اللعبة و Open Cloud ميزانية; يمكن أن يتم تقييد حركة مرور Open Cloud بواسطة الاستخدام داخل التجربة (وعكس ذلك). انظر Control rate limits للحصول على إرشادات إضافية.
تخزين البيانات القياسية
| نوع الطلب | API خادم اللعبة | API السحابة المفتوحة | حدود مشتركة (طلب في الدقيقة) |
|---|---|---|---|
| قراءة | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | احصل على إدخال تخزين البيانات | 300 + مستخدمين متزامنين × 40 |
| كتابة | SetAsync() IncrementAsync() UpdateAsync() | إنشاء، تحديث، زيادة إدخال تخزين البيانات | 300 + مستخدمين متزامنين × 20 |
| قائمة | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | قائمة تخزين البيانات، قائمة إدخالات تخزين البيانات، قائمة مراجعات إدخالات تخزين البيانات | 300 + مستخدمين متزامنين × 2 |
| إزالة | RemoveAsync() | حذف إدخال تخزين البيانات، حذف تخزين البيانات، استعادة تخزين البيانات المحذوف | 300 + مستخدمين متزامنين × 40 |
تخزين البيانات المرتبة
| نوع الطلب | API خادم اللعبة | API السحابة المفتوحة | حدود مشتركة (طلب في الدقيقة) |
|---|---|---|---|
| قراءة | GetAsync() UpdateAsync() | احصل على إدخال تخزين البيانات المرتبة | 300 + مستخدمين متزامنين × 40 |
| كتابة | SetAsync() IncrementAsync() UpdateAsync() | إنشاء، تحديث، زيادة إدخال تخزين البيانات المرتبة | 300 + مستخدمين متزامنين × 20 |
| قائمة | GetSortedAsync() | قائمة إدخالات تخزين البيانات المرتبة | 300 + مستخدمين متزامنين × 2 |
| إزالة | RemoveAsync() | حذف إدخال تخزين البيانات المرتبة | 300 + مستخدمين متزامنين × 40 |
التحكم في حدود المعدل
نظرًا لأن طلبات السحابة المفتوحة وخادم اللعبة مشتركة، من المهم التحكم بشكل مستقل في مقدار ما يمكن أن يستهلكه كل منهما من الميزانية.
خادم اللعبة
تتضمن الخوادم حدودًا مدمجة، كما هو موصوف أعلاه. استخدم مجموعة من SetRateLimitForRequestType() و GetRequestBudgetForRequestType() للحفاظ على التحكم الدقيق في مساهمة الخوادم الفردية في الميزانية الإجمالية.
السحابة المفتوحة
تتطلب طلبات السحابة المفتوحة حل تحديد معدلات خارجي. نوصي بإحدى النهجين التاليين:
- (بسيط) إضافة مهلة قصيرة بعد كل طلب، خاصة إذا كنت تستدعي نفس API في حلقة مستمرة. قم بتعيين هذه المهلة إلى 60 / (استھلاك الميزانية المطلوب في الدقيقة) ثوانٍ، كحد أعلى. لاحظ أن هذا الأسلوب لا يسمح بإرسال الطلبات دفعة واحدة.
- (موثوق) تنفيذ محدد معدل محلي باستخدام استراتيجية دلو متسرب.
تشمل أمثلة التعليمات البرمجية Node.js التالية تنفيذات مرجعية.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('The API_KEY environment variable is not set.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventory';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- إعداد قيود معدل لكل عملية (طلبات في الدقيقة) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// الحد الأعلى لكل عملية: 60 / (طلبات في الدقيقة) ثوانٍ.
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));
// ينفذ الطلب، ثم ينتظر مدة هذه العملية قبل الإرجاع.
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) // يجب أن يكون الجسم سلسلة
}, 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(`\nProcessing entry: ${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(`Response: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('An error occurred during execution:', error);
}
})();حدود الخادم
تحتوي كل خادمة على حد معدل قابل للتكوين لكل نوع طلب، بناءً على عدد اللاعبين في تلك الخادمة. تحصل الخوادم على دفعة إضافية لمرة واحدة من ميزانية الطلبات الإضافية عندما يتم إنشاؤها لأول مرة. استخدم GetRequestBudgetForRequestType() لتأكيد عدد طلبات تخزين البيانات التي يمكن للخادم الحالي إجراؤها في أي وقت.
هذه الحدود قابلة للتكوين من قبل المنشئ باستخدام SetRateLimitForRequestType() API. باستخدام واجهة البرمجة هذه، يمكن للمنشئ تكوين حدود معدلات تخزين البيانات الخاصة بهم لكل نوع طلب.
تطبق حدود معدل الحدود الافتراضية التالية إذا لم يتم استدعاء واجهة البرمجة:
تخزين البيانات القياسية
| نوع الطلب | DataStoreRequestType Enum | API خادم اللعبة | طلبات في الدقيقة |
|---|---|---|---|
| قراءة | StandardRead | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | 60 + numPlayers × 40 |
| كتابة | StandardWrite | SetAsync() IncrementAsync() UpdateAsync() | 60 + numPlayers × 40 |
| قائمة | StandardList | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | 5 + numPlayers × 2 |
| إزالة | StandardRemove | RemoveAsync() | 60 + numPlayers × 40 |
| RemoveVersion (Deprecated) | RemoveVersionAsync | RemoveVersionAsync() | 5 + numPlayers × 2 |
تخزين البيانات المرتبة
| نوع الطلب | DataStoreRequestType Enum | API خادم اللعبة | طلبات في الدقيقة |
|---|---|---|---|
| قراءة | OrderedRead | GetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| كتابة | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| قائمة | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| إزالة | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
حدود البيانات
يحدد تخزين البيانات مقدار البيانات التي يمكن استخدامها لكل إدخال.
يجب أن يكون اسم تخزين البيانات، اسم المفتاح، و النطاق جميعها تحت طول معين من الحروف. استخدم string.len() للتحقق من طولها.
تُخزن البيانات (قيمة المفتاح) أيضًا كسلسلة، بغض النظر عن نوعها الأولي. يمكنك التحقق من حجم البيانات باستخدام دالة JSONEncode(), التي تحول بيانات Luau إلى جدول JSON متسلسل.
| العنصر | أقصى عدد من الحروف |
|---|---|
| اسم تخزين البيانات | 50 |
| اسم المفتاح | 50 |
| النطاق | 50 |
| البيانات (قيمة المفتاح) | 4,194,304 لكل مفتاح |
حدود البيانات الوصفية
حدود عدد الحروف في البيانات الوصفية التي يحددها المستخدم.
| العنصر | أقصى عدد من الحروف |
|---|---|
| اسم المفتاح | 50 |
| القيمة | 250 |
| أزواج المفتاح-القيمة | 300 |
حدود الإنتاج
تحدد حدود الإنتاج لكل مفتاح الأداء الأمثل على خوادم Roblox. تنطبق كل حدود على كل مفتاح على حدة عبر جميع الخوادم في تجربة وتنتعش بشكل دوري.
تقوم Roblox بفحص استخدام الحصة المرتبطة بالمفتاح خلال الستين ثانية الماضية. إذا كان الاستخدام، بما في ذلك الطلب الحالي، ضمن حد الإنتاج، يتم الموافقة على الطلب. إذا تجاوز الاستخدام الحد، يتم رفض الطلب.
| نوع الطلب | API خادم اللعبة | API السحابة المفتوحة | الحد |
|---|---|---|---|
| قراءة | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | احصل على إدخال تخزين البيانات | 25 ميغابايت في الدقيقة |
| كتابة | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | إنشاء، تحديث، زيادة، حذف إدخال تخزين البيانات | 4 ميغابايت في الدقيقة |
بالإضافة إلى حدود الإنتاج المذكورة أعلاه، تنظم Roblox البيانات في أجزاء بناءً على مخطط داخلي. نتيجة لذلك، عندما يستقبل الخادم الخلفي حجمًا كبيرًا من الطلبات إلى نفس تخزين البيانات، قد يؤدي ذلك إلى مزيد من التقييد. بصرف النظر عن السبب، يظهر التقييد إما كأخطاء DatastoreThrottled أو KeyThrottled، اعتمادًا على ما إذا كان قد تم تجاوز حد الإنتاج لتخزين بيانات واحد أو مفتاح. تنطبق رسائل الخطأ هذه على كل من تخزين البيانات المرتبة والقياسية.
حدود التخزين
للحفاظ على استقرار التخزين وقابليته للتوسع، تستخدم مخازن البيانات حدًا على مستوى اللعبة لاستخدامك للتخزين.
يتكون هذا الحد من تخصيص أساسي لكل لعبة بالإضافة إلى تخصيص إضافي استنادًا إلى عدد المستخدمين مدى الحياة. المستخدم مدى الحياة هو أي مستخدم انضم إلى لعبتك مرة واحدة على الأقل.
يتم حساب حد التخزين باستخدام الصيغة التالية Total latest version storage limit = 500 MB + 1 MB × lifetime user count.
يتم قياس استخدام التخزين باستخدام الحجم المضغوط لأحدث إصدار من كل مفتاح. تقوم مخازن البيانات تلقائيًا بضغط بياناتك قبل التخزين، لذا تجنب ضغطها مسبقًا بنفسك. قد يضيف الضغط المسبق عبئًا غير ضروري على وحدة المعالجة المركزية وقد يقلل من فعالية ضغط مخازن البيانات المدمج. من خلال تخزين البيانات غير المضغوطة، يمكنك الاستفادة تلقائيًا من التحسينات في خوارزميات ضغط روبلوكس والتحديثات المستقبلية القائمة على المخططات.
فقط أحدث إصدار من كل مفتاح يُحسب تجاه استخدام التخزين الخاص بك. المفاتيح المحذوفة والإصدارات المتقادمة، رغم أنها لا تزال قابلة للوصول من خلال واجهات برمجة التطبيقات للإصدارات خلال فترة الاحتفاظ بها، لا تحسب تجاه استخدام تخزينك. ومع ذلك، فإن مخازن البيانات المحذوفة عبر أسلوب Open Cloud DeleteDataStore تظل تعتبر ضمن استخدام التخزين خلال فترة معالجة الحذف البالغة 30 يومًا، حتى يتم حذفها نهائيًا.