Модуль ОСени для синхронизации исполнения методов желудей
Допустим в вашем желуде есть какой-то критичный участок кода, который не должен исполнятся параллельно, и вы хотите сделать его потокобезопасным
// МойЖелудь.os
Процедура МойВажныйКод() Экспорт
// Потокоопасный код
КонецПроцедуры
Что-бы сделать его потокобезопасным нужно создавать Блокировку, корректно блокировать и разблокировать участки кода:
// МойЖелудь.os
Перем Блокировка;
Процедура МойВажныйКод() Экспорт
Блокировка.Заблокировать();
Попытка
// Потокоопасный код
Исключение
Блокировка.Разблокировать();
ВызватьИсключение ИнформацияОбОшибке().ПодробноеОписаниеОшибки();
КонецПопытки;
Блокировка.Разблокировать();
КонецПроцедуры
Блокировка = Новый БлокировкаРесурса();
И вот чтобы не писать весь этот бойлерплейт вам поможет данный модуль, нужно добавить всего лишь аннотацию Синхронизировано и ваш метод магическим образом становится потокобезопасным!
// МойЖелудь.os
&Синхронизировано
Процедура МойВажныйКод() Экспорт
// Потокоопасный код
КонецПроцедуры
По умолчанию синхронизация выполняется на самом желуде: все его методы с аннотацией Синхронизировано исполняются по очереди, а внешний код может встать в ту же очередь, заблокировав желудь:
Блокировка = Новый БлокировкаРесурса(МойЖелудь);
Чтобы синхронизировать методы разных желудей, передайте в аннотацию лямбда-выражение, которое вернёт общий объект синхронизации. Лямбда захватывает желудь, поэтому в ней доступны его поля, в том числе приватные, и экспортные методы:
// Отгрузка.os
&Пластилин
Перем Склад;
&Синхронизировано("() -> Склад")
Процедура Отгрузить() Экспорт
// Код, работающий со складом
КонецПроцедуры
Все методы, синхронизированные на одном складе, в том числе в других желудях, исполняются по очереди.
Важно:
Лямбда вычисляется один раз при создании желудя, после внедрения полей с аннотациейПластилин, но доФинальныйШтрих. Она должна вернуть объект: строки, числа и другие примитивные значения для синхронизации не подходят.ЭтотОбъектвнутри лямбды указывает на саму лямбду, а не на желудь; чтобы синхронизироваться на желуде, просто не передавайте лямбду.
Установка зависимостей и прогон тестов (OneUnit):
opm install -l --dev
oscript_modules/bin/oneunit e