|
|
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
Господа, добрый утро. В общем, заказчик захотел вполне стандартную фичу - чтоб развязать кучу модулей внедрить в проект ивенты. Сказано - сделано. для этого есть отличный функционал спринга - называется аппликейшн ивенты. Но потом пошли дальше - встала задача, во во-первых, сохранять в базу вообще ВСЕ ивенты, которые пробегали в приложении, в парах ивент+листенер. т.е. а) сохранять все ивенты, б) выискивать по коду все листенеры и тоже сохранять туда же. во-вторых, подрубить многопоточку - ну тут ах ох как два пальца. надо - берите. в-третьих, иметь возможность ПЕРЕЗАПУСКАТЬ обвалившиеся неотработавшие ивенты (и видеть это в базе - что обвалилось и т.п.). что сделал я? а) ввёл стандартную реализацию ивентов, б) параллельно дописал евент паблишер так, чтоб он выкашивал все ивенты и сериализовал в базу. и немного дописал аппликейшн-ивент класс. чтоб у каждого ивента появился свой уникальный уид при создании. в) сделал конфиг бин (бины), который сканит при старте вообще все бины приложения на предмет аннотации @eventlistenet и добавил (чтоб хоть как то оптимизировать и сканить только те бины, что реально надо, а не всё подряд) еще одну классовую аннотацию, указывающую что этот бин - сборник листенеров. И сборку всей даты в реестр. в1) сделал конфиг, чтоб стартовались все ивенты в многопоточке по умолчанию. прокинул в каждый ивентлистенер (нужный) контекст приложения. г) сделал на аспект-джее перехватчик (around) анноташки @EventListener и уже дополнил ее кодом, в котором перед стартом листенера мы ищем свою строчку в базе и ставим галочку "я листенер А, я начал обрабатывать событие Х". а после выполнения листенера снова идем в базу ищем строчку в базе связки листенер А+событие Х высчитываем сколько времени листенер отработал и кладем туда (я работал 5 секунд, событие Х обработано). или в случае если листенер плюёт ексепшн, то находим в базе строчку листенер А+событие Х и обновляем там статус - всё плохо, кэп. мы упали. д) добавил сервис, который можно запустить на скан таблицы ивент+листенер (статус фейл), который из нее вытаскивает все зафейленые ивенты и начинает их заново рассылать ивентлистенерам и смотреть - исполнились они или снова упали. что в канклюжене? а) это дикий оверхед который нафиг не нужен. тем более в нынешнем виде. б) решение не особо скалябельное - сейчас я бы пошел другим путём. в) драный аспекжэей НЕ воспринимает аннотацию транзакшнл внутри себя (в спринг бут) виавинг включить мне так и не удалось. г) со стороны всё выглядит замечательно - ты пользуешься паблишером как всегда и как все, делаешь ивенты как все, ставишь анноташечку как и при обычных ивентах и листенерах. с точки зрения другого программиста - никаких плясок с бубном чтоб расширить добавить дополнить. д) а теперь многопоточка - если речь идет о рассылке сообщений то тут вопросов как бы никаких нет. всё замечательно. )) и в 10 потоков работает и в 1. но вот с рестором начинается задница! и задница именно в многопоточке. где я НЕ понимаю как это синхронизировать и главное на что. можно аспект эраунд сделать синхронайзд - но тогда всё выполняется в один поток (и правильно :)). но это не вариант. собссно проблема следующая. ивент работает так: 1) ивентлистенер перехватывает пропагандированный ивент. 2) включается аспект эраунд и начинает смотреть в базу ДО исполнялся ли ранее ивент (если да - то прерываем исполнение листенера) (если нет - то ставим галку в базу "начал исполнять ивент") 3) запускается само тело листенера 4) идем в базу находим строчку (листенер+ивент) и ставим галку ("я закончил выполнение"). в номральном сценарии всё ок. вопросов нет. запускаем режим перезапуска умерших листенеров. что для этого делаем? считываем ивент из таблицы который имеет умершие листенеры. снова паблишим его. что тут происходит? так как на ивент А. есть подписчики БЦДЕ. из них ЦД выполинил а БЕ упали - получается, что ивент получит ВСЁ-РАВНО 4 листенера. из них 2 их заигнорят, а два выполнят. что происходит у меня в коде - 2 как положено игнорят -- а 2 других могут исполниться 2-3-4 раза, при этом у одного статус будет ОК, а у другого фейлд )) или стартед (но так и не закончен). причем если 20 раз перезапустить этот кейс - то 20 раз будут разные результаты. иногда оно выполнится правильно. иногда нет )) проблема тут в том, что несколько потоков параллельно пытаются менять статусы и проверять статусы, и получается каша. в однопоточном режиме проблем никаких НЕТ. я не пойму на что мне синхронизироваться. пробовал создать конкурентную хашмапу и туда класть ключи в виде уид листенера + уид ивента на момент исполнения, и удалять по концовке - ниразу не помогло. ощущение что хашмапа работает так что разным потокам отдает разные значения. (наверное так и должно быть - хз) )) что делать то? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 11:28 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
продолжаю думки. я в многопоточке не силен к сожалению.. собссно какие тут варианты? а) думать на что синхронизироваться (вопрос хз как) б) вообще отказаться от операции апдейта )) и в базу строки только писать но не изменять (хз поможет ли). больше мыслей пока нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 11:33 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
andreykaTГоспода, добрый утро. В общем, заказчик захотел вполне стандартную фичу - чтоб развязать кучу модулей внедрить в проект ивенты. Заказчик вменяемый? Он знает что такое ивенты? Иди лучше к бизнесу работать. Там выставляют Функциональные требования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 13:29 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
да согласен.... Весьма контравершиал. Тем более, что то ради чего весь этот геморрой выстраивался, вероятность что случится - где то около нуля. т.е. реально на нужды приложения требовалось от этого сарая от силы 10% функционала (который был готов через полдня после озвучивания требований), остальные 3.5 дня угрохались на те 90% функционала, которые особо и не нужны. от слова совсем. но с другой стороны возможность поиграться с многопоточкой и понять почему в ней черт ногу сломать может. пока разбираюсь вот. похоже, придется освежить в памяти книжку канкарренси ин практиз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 14:34 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
andreykaT, Изучать лучше под требования бизнеса и вменяемого архитектора. Imho Удачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 14:45 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
пробелма в том, что тот, кто это планировал, как мне показалось, несколько смутно различает те ивенты, что летают внутри спрингового приложения, с теми ивентами, что бегают через стандартные месседж системы типа жмс, кафка и т.п., и с теми ивентами, что выплывают у тебя в браузере в уголке, когда ты на вебстранице какой-нибудь сидите. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 15:34 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
andreykaT, А от callback он ивенты отличает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 15:58 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
надо спросить. но да. путаница по ходу есть в результате которой родился вот этот описанный выше, совершенно бесполезный монстр. это всё круто но нафиг не надо. кстати, нашел ошибку. я ломал флоу. т.е. происходило то, что не должно было присходить - бежал тесткейс, и в параллели к нормальному флоу через приложение я случайно запустил второй поток (внутри теста) - который менял флажки в базе естественно, аспект и действовал согласно той логики деревянной, которую я в него вложил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 19:14 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
andreykaT, Да. Идет лесом базовые свойства транзакции - атом-ть, изол-ть, ... Imho ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 20:28 |
|
||
|
Spring, Aspectj, Events - многопоточный тупик.
|
|||
|---|---|---|---|
|
#18+
Даже и представить не могу что там можно было за полдня нареализовывать) народ месяцами вылизывает евент библиотеки..полдня это только на прикинуть поверхностно что и где должно быть)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2017, 12:18 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=63&tid=2122718]: |
0ms |
get settings: |
8ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
34ms |
get topic data: |
15ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 234ms |
| total: | 367ms |

| 0 / 0 |
