Repository navigation
Conversation
Прочитанные сущности хранилище запоминает в пуле своего потока исполнения (в данных потока), а не в одном пуле на все потоки. Внутри потока на идентификатор по-прежнему один экземпляр, а разные потоки получают разные экземпляры одной строки: чтение в одном потоке больше не стирает несохраненные правки другого и не смешивает снимки строки, прочитанные в разное время. ХранилищеСущностей.Закрыть() отбрасывает экземпляры всех потоков: пул своего потока освобождается сразу, пулы других - при их следующем обращении к хранилищу (по номеру очистки). Потерянное обновление при двух сохранениях одной строки это не лечит: остается сохраненное последним, это описано в документации. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughИзменения регистрируют типы активных записей и переводят пул сущностей на хранение в данных текущего потока. При очистке хранилища пулы других потоков заменяются при следующем обращении. Тесты и документация описывают изоляцию экземпляров и очистку пулов. ChangesЭкземпляры сущностей и пулы потоков
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant Thread as Поток исполнения
participant Storage as ХранилищеСущностей
participant Connector as РаботаСКоннекторами
participant ActiveRecord as АктивнаяЗапись
Thread->>Storage: Запросить пул текущего потока
Storage-->>Thread: Вернуть соответствие экземпляров
Thread->>Connector: Прочитать сущность по идентификатору
Connector->>Connector: Найти экземпляр в пуле
alt Экземпляр отсутствует
Connector->>ActiveRecord: Создать экземпляр сущности
ActiveRecord-->>Connector: Вернуть экземпляр
Connector->>Connector: Вставить экземпляр в пул
end
Connector-->>Thread: Вернуть экземпляр сущности
Suggested reviewers: Merge Risk: ⚪ Minimal · up to This change separates entity pools by thread. The reviewed concerns do not establish a new material regression, so the PR is ready for normal pre-merge checks. Architecture SummaryArchitecture risk: 🔵 Low · up to The change affects 4 systems. Changed systems: Architecture concerns Review detailsSystems and components
Before / after behavior
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🧪 Generate unit tests (beta)
🛠️ Fix failing CI checks 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Кролик хранит сущность в потоке, Comment |
…го один раз Пул сущностей на поток исполнения создает экземпляры заново в каждом потоке, а АктивнаяЗапись строила декоратор компиляцией модуля на каждый экземпляр (около 1,8 мс). Теперь тип активной записи регистрируется через ЗарегистрироватьВСистемеТипов один раз на класс сущности, и экземпляр создается из него через Новый (около 0,14 мс). Чтение 200 сущностей в новом потоке - 31-57 мс вместо 285-359. Тип общий у всех менеджеров процесса, поэтому хранилище и модель экземпляр получает после создания: значения по умолчанию остались бы в реестре типов decorator навсегда и держали бы хранилище первого менеджера. Тип сущности экземпляра определяется через ОбработкаДекоратора.ИсходныйТип: ТипЗнч у него теперь зарегистрированный тип, а не Сценарий. Нужна decorator 3.1.1 с потокобезопасной регистрацией типов (nixel2007/decorator#34). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| @@ -1,12 +1,16 @@ | |||
| #Использовать decorator | |||
| #Использовать reflector | |||
There was a problem hiding this comment.
объект Рефлектор не из библиотеки reflector
There was a problem hiding this comment.
Да, Рефлектор встроен в движок, а reflector даёт только РефлекторОбъекта и ИнтерфейсОбъекта. Убрал #Использовать reflector в 4994b74.
Заодно влил свежий master (collectionos 0.8.4, oneunit 0.5.2). Без PostgreSQL на 2.2.0 и 2.3.0-next — 305 из 305.
Рефлектор - встроенный тип движка, библиотека reflector дает только РефлекторОбъекта и ИнтерфейсОбъекта. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Требует decorator 3.1.1 (nixel2007/decorator#34, «Потокобезопасная регистрация типов»). Он выпущен, вместе с ним приходит зависимость
osparser0.1.0. В ветку влит текущийmaster(lambdas 0.3.5 из #157).Что чинит
Экземпляры прочитанных сущностей. Пул сущностей хранилища был один на все потоки: потоки получали один и тот же экземпляр строки и без согласования заполняли его поля. Для каждого дефекта сначала написан тест, красный на
master, потом исправление.masterКак теперь
СоответствиевТекущийПоток().Данныепод ключом хранилища. Пишет и читает его только свой поток, поэтому блокировки нет.ХранилищеСущностей.Закрыть()иМенеджерСущностей.Закрыть()отбрасывают экземпляры всех потоков. Пул своего потока освобождается сразу, пулы других — при их следующем обращении к хранилищу (по номеру очистки,АтомарноеЧисло) или по завершении потока.Цена экземпляров в новом потоке
Общий пул на
masterкешировал не данные — каждое чтение и так идёт в БД, — а собранные экземпляры.АктивнаяЗаписьстроила декоратор компиляцией модуля (ЗагрузитьСценарийИзСтроки) на каждый экземпляр, около 1,8 мс. С пулом на поток каждый новый поток (фоновое задание, запрос веб-сервера) платил бы эту цену заново за каждую прочитанную сущность.Поэтому второй коммит переводит
АктивнаяЗаписьна тип декоратора, зарегистрированный один раз на класс сущности (ЗарегистрироватьВСистемеТипов). Экземпляр создаётся из него черезНовый._ХранилищеСущностейи_ОбъектМоделипроставляются экземпляру после создания. Значения по умолчанию остались бы в реестре типов decorator навсегда и держали бы хранилище первого менеджера.АктивнаяЗапись.ТипСущности— черезОбработкаДекоратора.ИсходныйТип:ТипЗнчэкземпляра теперь зарегистрированный тип, а неСценарий.Замер, InMemory,
Получить200 авторов:Создание экземпляра: 1,7–1,9 мс → 0,13–0,145 мс; регистрация типа — 10–20 мс один раз на класс.
Что меняется снаружи
ПолучитьПулСущностей()отдаётСоответствиетекущего потока вместо общейСинхронизированнаяКарта.ТипЗнчэкземпляра активной записи — зарегистрированный типАктивнаяЗапись_<uuid>, а неСценарий. Исходный класс по-прежнему отдаётОбработкаДекоратора.ИсходныйТип.decoratorподнята до 3.1.1.docs/ПотокобезопаснаяРаботаСБД.md.Тесты
Новый набор
ЭкземплярыСущностейВПотоках(InMemory):ЧтениеВДругомПотокеНеЗатираетПравкуЭкземпляра;ПотокиПолучаютРазныеЭкземплярыОднойСтроки;ЧтениеПосредиСборкиВДругомПотокеНеСмешиваетСнимки— новая фикстураНаблюдательЗадержкиЧтениядержит задание на вложенном чтении ссылки;ОчисткаХранилищаОтбрасываетЭкземплярыДругихПотоков: зелёный и наmaster, мутант «без номера очистки» тест поймал.Первые три на
masterкрасные.В
ХранилищеСущностей:ЭкземплярыСоздаютсяИзЗарегистрированногоТипа— красный до второго коммита;ЭкземплярДругогоМенеджераСохраняетсяЧерезСвоеХранилище: тип общий у менеджеров, а экземпляр сохраняется через своё хранилище. Мутант «служебные поля — значения по умолчанию первой регистрации» тест поймал, а с ним ещё пять тестов набора.Полный прогон:
c2ff803, вместе сosparser0.1.0): 2.2.0 — 321 из 321 (дважды), 2.3.0-next+a02323a1 — 321 из 321 (дважды), 2.2.0 только PostgreSQL — 304 из 304;master, без PostgreSQL: 2.2.0 — 305 из 305, 2.3.0-next+a02323a1 — 305 из 305.На 2.2.0 остаётся гонка движка, которая была и на
master: первое параллельноеНовыйодного типа портит кэш фабрик типов (EvilBeaver/OneScript#1762, в 2.3.0-next исправлено). Этот PR её не чинит.🤖 Generated with Claude Code
Summary by CodeRabbit