Cluster · разработчикам
Mekansm
Cluster использует Mekansm 3.0.0 для состояния службы и данных юзерботов. Это отдельная зависимость, её версия закреплена в pyproject.toml.
Базы
Ядро открывает центральную базу control/state.mekansm. У каждого юзербота своя state.mekansm, расположенная в его каталоге данных или ограниченном томе. Один файл открывает только один владелец, повторное открытие блокируется.
Центральная база хранит профили, подписки, Telegram-подключения, публикации и управление. Пользовательская база хранит разделы модулей, настройки, журнал, расписание и учёт места. Пакеты, сборки и файлы хранятся отдельно.
Сайт, модуль и терминал работают через API. Физический файл базы им не передаётся.
Шифрование
Ядро использует ключ из закрытого файла размером 32 байта. Этот ключ применяется к центральной и пользовательским базам. Отдельный ключ на профиль не создаётся.
Telegram-подключение хранится как StringSession в зашифрованной служебной базе. Отдельный SQLite-файл сессии не создаётся.
Шифрование базы не распространяется на скачанный ZIP с резервной копией. Хранение и защита внешних копий настраиваются отдельно. При потере ключа восстановить зашифрованную базу нельзя.
Операции Cluster
Mekansm предоставляет хранение, транзакции и проверку файла. Поверх них ядро реализует:
- Версию схемы и отказ от неизвестной версии.
- Индексы почты, логина, Telegram ID, ботов, публикаций и установок.
- Одноразовые коды, входы сайта, TOTP и отзыв доступа.
- Повтор запроса по ID без повторного применения операции.
- Сохранённую очередь со сроком владения задачей.
- Разделы экземпляров, срок хранения записи и очистку.
- Квоту, резервы места и учёт файлов.
- Резервные копии и восстановление после сбоя.
Эти правила относятся к Cluster. Движок сам не знает о профилях, правах модуля или подписке.
Данные модуля
app.db обращается к разделу текущего экземпляра. Для получения нужен db.read, для изменений db.write.
class Module:
async def init(self) -> None:
count: int = await app.db.get("counter", default=0)
await app.db.set("counter", count + 1)get получает значение, set сохраняет, delete удаляет. keys получает список ключей и курсор следующей порции. Срок хранения задаётся параметром ttl в секундах.
Ключ должен быть непустой строкой до 4096 байт в UTF-8. Значение передаётся JSON. Размер записи вместе с внутренним ключом и служебными полями не может превышать половину рамки протокола. При стандартной рамке 1 MiB предел составляет 512 KiB.
Если записи нет или её срок истёк, get возвращает default. Сохранённый JSON null возвращается как None, даже если указан другой default.
db.full позволяет выбрать другой прикладной раздел того же юзербота через module и slot. Для самой операции также нужны db.read или db.write. Служебная база и другой юзербот остаются недоступны. Параметры методов приведены в SDK.md.
Квота
Место проверяется перед увеличением данных. Учитываются ключи, значения, файлы, журнал, расписание, публикации, сборки, копии и резерв терминала. До долгой операции создаётся резерв. При ошибке собственный резерв освобождается.
Истёкшая запись перестаёт возвращаться сразу, физически удаляется обслуживанием. После удаления освобождается её логический размер.
Размер файла Mekansm может быть больше суммы действующих записей: старые записи остаются до уплотнения. При --volumes том резервирует две пользовательские квоты плюс 64 MiB. Этот запас нужен для уплотнения и восстановления, модуль не может использовать его через API.
Индекс движка занимает память. Число записей и лимиты хранилища нужно учитывать при выборе ресурсов сервиса.
Копии
Копия экземпляра содержит его данные, конфигурацию, страницы, сетевой профиль и файлы. Полная копия также содержит настройки юзербота, журнал, расписание и рабочие файлы терминала. Сессии, входы сайта и ключ службы не включаются.
Договоры сохраняются как описание. Восстановление архива не создаёт согласие другого участника. Включённые в копию события восстанавливаются вместе со своим счётчиком.
Перед обновлением можно сохранить одну предыдущую копию экземпляра. Следующая заменяет её после успешного создания. На время замены нужно место для обеих копий. Период и количество полных копий настраиваются отдельно.
Операторская копия создаётся при остановленных службах. Она проверяет базы и сохраняет состояние без Telegram-сессий и прежних входов. Для восстановления нужен отдельно сохранённый ключ. Состав архивов и команды приведены в STORAGE.md.
Обновление
При открытии ядро проверяет версию прикладной схемы. Неизвестная версия отклоняется. Файл базы не передаётся другому процессу, пока им владеет ядро.
Перед сменой версии Mekansm создаётся копия. Затем проверяются открытие данных, тесты Cluster и восстановление копии. Версия зависимости и версия схемы Cluster проверяются отдельно.