# الحفظ الدائم

> كيف تخزّن خدمة LMSP حالتها، بقاعدة بيانات SQLite مضمَّنة، والجداول التي ينبغي الاحتفاظ بها، والقواعد المعاملاتية للمهام والأحداث، ومدة الاحتفاظ، والاستعادة عند البدء.

Source: https://madeforagent.com/ar/lmsp/1.0/persistence/
Language: ar
Specification: LMSP 1.0 (draft)
Updated: 2026-11-08

## 11.1 التخزين {#storage}

**ينبغي** للخدمة أن تحتفظ بحالتها في قاعدة بيانات [SQLite](https://www.sqlite.org/) مضمَّنة. مجموعة مقترحة من الجداول:

| الجدول | المحتوى |
| --- | --- |
| `service_config` | هوية الخدمة وإعداداتها. |
| `clients` | العملاء المقترنون، وتجزئات الرموز، والنطاقات. |
| `models` | البيانات الوصفية للنماذج وبصمات المحتوى. |
| `responses` | الاستجابات المخزَّنة. |
| `tasks` | المهام غير المتزامنة. |
| `task_events` | سجل أحداث كل مهمة، بأرقام تسلسلية. |
| `idempotency_keys` | مفاتيح التكرار الآمن وبصمات الطلبات ونتائجها. |

**يجب** أن تبقى ملفات النماذج خارج قاعدة البيانات. فالقاعدة تحتفظ بالبيانات الوصفية وبصمات المحتوى فقط.

أسماء الجداول وتخطيطها خيار تنفيذ. أما ما يلاحظه العملاء، وما لا بد أن يكون متوافقًا بين التنفيذات، فهو السلوك الموصوف في القسمين التاليين.

## 11.2 القواعد {#rules}

أيًّا كان التخزين الذي تستخدمه الخدمة، فإن القواعد التالية تسري عليها:

- **يجب** أن تحفظ المهمة قبل أن تعيد `202 Accepted`.
- **يجب** أن تحدّث الأرقام التسلسلية للأحداث وحالة المهمة في المعاملة نفسها.
- **يجب** أن تجعل انتقال الإلغاء ذريًا، لتفادي سباق مهمة تُلغى ثم تكتمل.
- **ينبغي** أن تحتفظ بالمهام والأحداث المنتهية طوال مدة احتفاظ قابلة للضبط.
- **لا يجوز** أن تحذف المهام غير المنتهية أثناء تنظيف السجلات.
- **يجب**، عند البدء، أن تفحص المهام المتبقية `queued` و`loading` و`running` و`cancelling` وتطبق سياسة إعادة التشغيل لكل منها ([القسم 7.5](https://madeforagent.com/ar/lmsp/1.0/tasks.md#restart)).

## 11.3 الاستعادة عند البدء {#recovery}

يبيّن الجدول الحالة التي تنتقل إليها المهمة المتبقية بحسب سياسة `on_restart` الخاصة بها:

| الحالة المكتشفة عند البدء | `fail` | `retry` | `resume` |
| --- | --- | --- | --- |
| `queued` | `failed` | `queued` | `queued` |
| `loading` | `failed` | `queued` | `queued` |
| `running` | `failed` | `queued` | `running`، بالمتابعة من اللقطة |
| `cancelling` | `cancelled` | `cancelled` | `cancelled` |

المهمة التي تنتقل إلى `failed` تتلقى رمز الخطأ `server_restarted` وحدث `response.failed`. والمهمة التي تنتقل إلى `cancelled` تتلقى حدث `response.cancelled`. وتُكتب الحالة الجديدة وحدثها في معاملة واحدة ([القسم 11.2](https://madeforagent.com/ar/lmsp/1.0/persistence.md#rules)).
