- Основная реализация библиотеки находится в
src/ru/BSL/OpenIntegrations. - Если поведение кода и тестов расходится, в первую очередь считать этот каталог источником истины.
- Английская версия кода, находящаяся в
src/enне требует доработки и синхронизируется с русской версией автоматическими пайплайнами
- Основные BSL-тесты находятся в
src/ru/BSL/Tests. - При разборе бизнес-логики анализировать эти тесты
- Changelog релизов ведётся в
service/releases.json. - Если нужно добавить запись в описание релиза, дополнять массив
changesпервого элемента массива (текущий, ещё не выпущенный релиз с наибольшей версией). - Добавлять пункт только если его ещё нет в
changesэтого релиза; дублировать одно и то же изменение в нескольких релизах не нужно. - У каждого пункта
changes— поляlib,icon,description_ru,description_en(см. существующие записи в файле).
- Зеркальные файлы OneScript находятся в
src/ru/OInt(включаяsrc/ru/OInt/tests). - Использовать этот каталог для проверки CLI/runtime-паритета, но не как первый источник при разборе BSL-регрессий.
- Эти зеркала не требуют ручной доработки — изменения затираются синхронизацией из
src/ru/BSL(в пользу русской BSL-версии). - Английское зеркало
src/enсинхронизируется тем же пайплайном; править его вручную не нужно.
Также генерируются в CI/CD автоматически (не коммитить вручную):
| Артефакт | Каталог / пример |
|---|---|
| OneScript API и тесты | src/ru/OInt/api/…, src/ru/OInt/tests/… |
| EN-зеркало BSL | src/en/BSL/… |
| CLI-описание библиотеки | src/ru/cli/data/Classes/index/<lib>.json (regions, methods, --param) |
| CLI-тесты | OPItc_* — из модулей OPIt_* |
| Документация (MDX, examples, results) | docs/ru, docs/en — из тестовых модулей |
Ручная правка в RU BSL обязательна для: OPI_*, OPIt_*, регистрации в OPI_ПолучениеДанныхТестов, записи в lib.json, метаданных .mdo, releases.json (см. чеклист ниже).
- У каждого функционального модуля есть два связанных тестовых модуля с тем же базовым именем:
- основные тесты с префиксом
OPIt_ - тесты CLI с префиксом
OPItc_ - функциональные модули используют префикс
OPI_
- основные тесты с префиксом
- Не редактировать модули
OPItc_вручную: CLI-тесты генерируются автоматически в CI-пайплайне из модулейOPIt_. - Каждый тестовый модуль должен содержать:
- область
ЗапускаемыеТестыс процедурами-обертками - область
АтомарныеТестыс атомарными проверками
- область
- Запускаемые тесты вызывают несколько атомарных.
- Количество атомарных тестов должно соответствовать количеству экспортных методов функционального модуля
OPI_*. - Дополнительно допустимы атомарные тесты
Расширенная_*(проверка ошибок FFI, повторного connect, лога при connect и т.п.) — они не входят в подсчёт «1 метод = 1 тест» и не попадают в онлайн-документацию как примеры API. - Количество запускаемых тестов должно соответствовать количеству областей функционального модуля (плюс отдельная область
РасширеннаяПроверка, если естьРасширенная_*тесты). - Текст тестовых модулей используется для формирования примеров кода в документации
- Служебные комментарии
//SKIPи//ENDиспользуются для исключения частей кода теста при формировании примера для документации.// SKIPпозволяет исключить конкретную строку внутри теста,//END- завершает запись примера. Весь служебный код, который идет после//ENDне попадает в пример кода для документации - В каждом атомарном тесте должен быть хотя бы один вызов
OPI_ПолучениеДанныхТестов.Обработатьс незаполненным параметромВариант(основной сценарий). Это первый такой вызов в процедуре, он размещается до//END; его результат попадает в онлайн-документацию как пример результата метода. Дополнительные варианты проверяются последующими вызовамиОбработатьс заполненнымВариант— они идут после//ENDи в пример документации не включаются - При формировании атомарных тестов нельзя выносить повторяющийся код в служебные функции, так как это может привести к недопониманию при их использовании в качестве примеров для документации
- В спорных/неочевидных ситуациях ориентироваться на существующие тесты как на каноничные примеры.
- В начале
ПолучитьТаблицуТестовдобавить константу секции, напримерLDAP = "LDAP"(имя должно совпадать с аргументомСформироватьТестыЯкс/Обработать). - Каждый запускаемый тест должен быть указан в
ПолучитьТаблицуТестовв модулеOPI_ПолучениеДанныхТестов. - В
OPI_ПолучениеДанныхТестовтакже находятся функции-проверки:- по одной функции-проверке на каждый атомарный тест
- с возможным ветвлением внутри по параметру
Вариант
- В
OPI_ПолучениеДанныхТестовнельзя вызывать методы функциональных модулей библиотеки (OPI_MessagePack,OPI_Lua,OPI_Telegramи т.п.). Модуль проверок должен оставаться независимым от тестируемых API. Если для проверки нужны подготовленные данные (десериализация, round-trip, повторный вызов метода), это делается в атомарном тестеOPIt_*и передаётся вОбработать/ОбработатьCLIчерез дополнительные параметры (Восстановленное,Исходноеи т.д.).
- Формат имени атомарного теста:
<ИмяМодуляБезПрефикса>_<ИмяМетодаФункциональногоМодуля>
- Формат имени запускаемого теста:
<ЛюбоеСокращениеИмениМодуляБезПрефикса><ИмяОбласти>
- Формат имени функции-проверки:
Проверка_<ИмяАтомарногоТеста>
Обязательный шаблон для любой новой нативной компоненты и для переработки существующих. Не создавать add-in «с нуля» в монолитном lib.rs с Arc<Mutex<…>> — сразу закладывать структуру ниже.
Каноничные примеры: src/addins/postgres, mysql, sqlite, mssql, mongodb, ftp, zeromq; серверы — tcp_server, http_server, ws_server.
| Уровень | Где | Что ловит |
|---|---|---|
| FFI | common-core: call_as_func → catch_panic |
Паника в тонкой обёртке addin (JSON/Janx, маршрутизация) |
| Backend | common-backend: поток worker + catch_panic на цикл handler |
Паника в драйвере; после фатала — health, следующие call/send → Err |
catch_unwind только на FFI не заменяет worker-поток: не решает !Send соединений (SQLite), гонки при параллельных вызовах из 1С, poisoned Mutex вокруг драйвера.
Не защищает ни один уровень: segfault/abort в C-библиотеке драйвера — падает весь процесс 1С. Изоляция только отдельным процессом (вне этой схемы).
Worker-поток сериализует работу с драйвером, но не защищает поля и флаги на стороне AddIn: started, logger, datasets, вызовы делегата в backend/common-server. Если платформа держит один экземпляр компоненты и вызывает методы из разных потоков (параллельные задания, внешний хостинг, общий кэш объекта), без mutex на оболочке возможны гонки — даже при корректном worker.
Обязательно в addin.rs (и в server-wrapper.rs, где есть обёртка):
Arc<Mutex<State>>— backend-делегат, служебное состояние, logger; все FFI-методы черезcommon_utils::lock_unpoisoned;- для SQL с dataset —
datasetsвнутри того жеState, не отдельное поле наAddIn(вlib.rs— тонкиеdatasets_*наAddIn).
Свойства getset (connection_string, server_address, address и т.п.) допустимо оставить на AddIn вне mutex; методы, которые читают их вместе с State, берут lock и при необходимости клонируют строку до обращения к backend (см. grpc connect).
Это не отменяет запрет ниже: Arc<Mutex<соединение/драйвер>> на addin по-прежнему нельзя — драйвер только в worker/Session.
src/addins/<name>/src/
lib.rs — METHODS, get_params_amount, cal_func, impl_addin_exports
addin.rs — тонкий AddIn: FFI-методы, `Arc<Mutex<State>>` на оболочке, без Mutex вокруг драйвера
backend.rs — *Backend: настройки до connect, ленивый поток, SetLogger
worker.rs — WorkerCommand, Session, spawn_thread, вся работа с драйвером
query.rs — только если есть отдельная логика SQL/запросов (MSSQL, Postgres, …)
settings.rs — разбор/хранение настроек connect (по необходимости)
operations.rs — парсинг Janx-параметров, маппинг в API драйвера (по необходимости)
release.bat — CARGO_NAME, LIB_NAME, вызов ../build.bat
Сборка: корневого Cargo workspace нет — каждый addin собирается отдельно. После cargo check для проверки компиляции запускать release.bat в каталоге addin. Скрипт кросс-компилирует бинарники и формирует zip в четыре места: src/ru/OInt/addins/OPI_<Name>.zip, src/en/OInt/addins/…, CommonTemplates/OPI_<Name>/Template.addin (ru и en). Файл Template.addin — артефакт сборки, обычно в gitignore; в репозиторий коммитится только .mdo шаблона.
Особые сборки (Win7, static OpenSSL): ветка addins-special, см. src/addins/special/README.md и docs/ru/md/Start/Component-requirements.md.
Не использовать в новом коде:
Arc<Mutex<Драйвер>>на стороне addin;- создание backend-потока в
new()(только лениво при первом connect/операции —ensure_thread); - дублирование логики connect/execute в
lib.rs.
| Тип драйвера | Крейт | Поток | Примеры |
|---|---|---|---|
| Синхронный API | SyncBackendThread |
Обычный std::thread, без tokio |
postgres, mysql, sqlite, ftp |
| Async / tokio внутри драйвера | BackendThread |
Поток + Runtime::new() в worker |
mssql, mongodb, zeromq |
| Долгоживущий сервер (listen/accept) | common-server::Backend |
Внутри — BackendThread |
tcp_server, http_server, ws_server |
common-server — тот же канал команд, но свой API (send_command, handle_async_command); не смешивать с паттерном addin/backend/worker без необходимости.
common-core— макросы FFI,catch_panicна границе.common-backend—BackendThread/SyncBackendThread.common-logs—Logger,log!,SetLogger/GetLogsна FFI.common-janx—JanxValue,janx!,FromJanx/IntoJanxдля бинарных полей и составных ответов.common-tcp— TLS, proxy,create_tcp_connection(FTP, БД с TLS).common-dataset— только где есть пакетные SQL/dataset (MSSQL).
- Поля:
thread: Option<…>, настройки до connect (tls,proxy, строка подключения),logger: Option<Arc<Logger>>. set_logger/set_tls— только до установления соединения.connect→ensure_thread()→thread.call(WorkerCommand::Connect { … }).close/Drop→shutdown(Some(WorkerCommand::Shutdown)).get_logs— читать изLoggerна стороне addin/backend (не из worker), если logger хранится в backend.
enum WorkerCommand— одна варианта на операцию; ответы черезmpsc::Sender<Result<…>>илиSender<String>для готового JSON.struct Session—client/connection,logger.fn log(&self, …)—common_logs::log!(logger, …).spawn_thread— единственное место циклаwhile let Ok(cmd) = rx.recv().- Вся работа с
FtpStream/Client/Connection— только внутри этого потока.
Добавить в METHODS (перед Version):
SetLogger— JSON-конфиг (Logger::from_json);GetLogs—count, ответ{ result, logs, total, returned }.
Порядок на стороне BSL (OPI_*): настройки → SetLogger (если передано Логирование) → connect/open.
Модуль: src/ru/BSL/OpenIntegrations/src/CommonModules/OPI_<Имя>/Module.bsl + OPI_<Имя>.mdo.
Шапка модуля (используется CI для документации и CLI):
// OneScript: ./OInt/api/<cli>/Modules/OPI_<Имя>.os
// Lib: <Имя в UI>
// CLI: <ключ в lib.json>
// DocsCategory: …
// DocsNameRU: …
// DocsNameEN: …Обёртка: #Если Не ВебКлиент Тогда // !OPI … #КонецЕсли.
Паттерны:
OPI_Компоненты.ПолучитьКомпоненту("<Имя>")→ объектAddIn.OPI_<Имя>.Main; жёсткого реестра компонент вOPI_Компонентынет.ЭтоКоннектор:Строка(ТипЗнч(Значение)) = "AddIn.OPI_<Имя>.Main".- Сложные параметры FFI:
OPI_Компоненты.СериализоватьJanx→ вызов метода компоненты →ДесериализоватьJanx. - TLS/прокси:
OPI_Компоненты.УстановитьTls,ПолучитьНастройкиTls(если применимо).
В области основных методов:
ПолучитьНастройкиЛогирования→ делегат вOPI_Компоненты.ПолучитьНастройкиЛогирования;ПолучитьЛог→OPI_Компоненты.ПолучитьЛог;- в
ОткрытьСоединение(или аналог) — необязательный параметрЛогирование, вызовКоннектор.SetLoggerдоConnect.
| Объект | Путь |
|---|---|
CommonModule OPI_<Имя> |
OpenIntegrations/src/CommonModules/OPI_<Имя>/OPI_<Имя>.mdo |
| CommonTemplate addin | OpenIntegrations/src/CommonTemplates/OPI_<Имя>/OPI_<Имя>.mdo (templateType=AddIn) |
Тесты OPIt_<Имя> |
Tests/src/CommonModules/OPIt_<Имя>/OPIt_<Имя>.mdo |
Зарегистрировать в обоих Configuration.mdo:
src/ru/BSL/OpenIntegrations/src/Configuration/Configuration.mdo—CommonTemplate.OPI_<Имя>,CommonModule.OPI_<Имя>;src/ru/BSL/Tests/src/Configuration/Configuration.mdo—CommonModule.OPIt_<Имя>(иOPItc_<Имя>появится после генерации в CI).
UUID в .mdo — новый уникальный на каждый объект.
- Добавить ключ в
src/ru/cli/data/Classes/index/lib.json:"<cli>": "OPI_<Имя>". - Файл
src/ru/cli/data/Classes/index/<cli>.json(regions, methods, CLI-параметры) генерируется в CI из BSL-модуля и комментариев// Lib,// CLI,@paramв тестах — править вручную не нужно. - Если компоненту в CLI-тестах нужно передавать не сам объект addin, а сериализованные настройки — добавить ветку в
ОбработатьПараметрКомпонентыCLIвOPI_ПолучениеДанныхТестов(по образцуOPI_RCON→GetSettings(),OPI_LDAP→GetConfiguration()).
Интеграционные тесты читают параметры из OPI_ПолучениеДанныхТестов.ПолучитьТестовыеДанные() (секреты CI / локальный конфиг). Для новой библиотеки завести осмысленные ключи, например LDAP_URL, LDAP_BindDN, LDAP_Password, LDAP_Base.
Запускаемый тест *_РасширеннаяПроверка: в начале УстановитьПризнакТестаCLI(Ложь) и выход при ЭтоТестCLI() — см. OPIt_RCON, OPIt_LDAP.
OPIt_<Имя>: областиЗапускаемыеТесты/АтомарныеТестыпо правилам выше.- В запускаемый тест основных методов —
<Модуль>_ПолучитьНастройкиЛогирования,<Модуль>_ПолучитьЛог(по образцуOPIt_MSSQL). - Атомарные тесты с
//ENDдля документации; без выноса повторов в служебные процедуры. OPI_ПолучениеДанныхТестов: константа секции, записи вПолучитьТаблицуТестов, функцииПроверка_*(для логирования — веткиФайл,Память,КакСтрока).- Не править
OPItc_*вручную — модуль появится/обновится в CI изOPIt_*. - Количество атомарных тестов (без
Расширенная_*) = количеству экспортных методовOPI_*.
service/releases.json— пункт вchangesпервого (невыпущенного) релиза:lib,icon(путьmedia/<Lib>.png),description_ru,description_en.- Иконка библиотеки для changelog и docs — добавить в
media/(если ещё нет). - Страницы документации, sidebars, examples — генерируются из тестов в CI; достаточно корректных
OPIt_*с//ENDи шапкиOPI_*. - Для addin-библиотек с TLS: на странице инструкции в docs появится предупреждение об OpenSSL, если в шапке модуля указана компонента — см.
docs/ru/md/Start/Component-requirements.md.
- Логирование часто включается третьим аргументом
Start, а не отдельнымSetLoggerдо connect (см.tcp_server,http_server,ws_server). - Состояние — accept/handle в
common-server, неSession { sql client }. - BSL-тесты логирования — по тому же принципу, но вызов через
Запустить/ параметры старта.
Rust
- Создать
src/addins/<name>/сCargo.toml,release.bat. - Завести
lib.rs,addin.rs,backend.rs,worker.rs(+query.rs/settings.rs/operations.rsпо необходимости). - Выбрать
SyncBackendThreadилиBackendThread(илиcommon-serverдля listen-сервера). - Заложить
SetLogger/GetLogsиlog!в connect/операциях. cargo checkв каталоге addin, затемrelease.batдля zip/Template.addin.
BSL и 1С
OPI_<Имя>/Module.bsl+OPI_<Имя>.mdo; регистрация вOpenIntegrations/.../Configuration.mdo.CommonTemplates/OPI_<Имя>/OPI_<Имя>.mdo(бинарникTemplate.addin— из сборки).OPIt_<Имя>/Module.bsl+OPIt_<Имя>.mdo; регистрация вTests/.../Configuration.mdo.OPI_ПолучениеДанныхТестов: константа,НовыйТест(...), всеПроверка_<Имя>_*; при необходимости — ветка вОбработатьПараметрКомпонентыCLI.
Интеграция и релиз
src/ru/cli/data/Classes/index/lib.json— ключ CLI.service/releases.json— запись в текущий релиз; иконка вmedia/.- Не править вручную:
src/ru/OInt,src/en,OPItc_*,docs/*,<cli>.json— обновит CI.
Те же шаги, что для новой, плюс:
- Разнести монолитный
lib.rs; убратьArc<Mutex<драйвер>>, заложитьArc<Mutex<State>>на FFI-оболочку (см. «Синхронизация FFI-оболочки»). - Перенести клиент в
Sessionworker-потока; поток — только ленивыйensure_thread. - Сохранить совместимость FFI: номера/имена методов, JSON-поля, намеренные побочные эффекты (например задержки в
cal_func).
| Задача | Смотреть |
|---|---|
| Новая sync-клиент + SQL | src/addins/postgres |
| Новая sync-клиент без SQL | src/addins/ftp |
| Новая async-клиент | src/addins/mssql, mongodb |
| BSL + тесты с нуля | OPI_RCON, OPIt_RCON (простой addin) или OPI_PostgreSQL, OPIt_MSSQL (SQL) |
| Новый сервер | src/addins/tcp_server + commons/common-server |
| Полный чеклист новой библиотеки | раздел «Чеклист: новая компонента (end-to-end)» выше |