Блокировка документов по http (?)

VladSh

начинающий
Lotus Team
11.12.2009
1 794
158
BIT
199
Появилась идея вынести блокировки в какое-то централизованное место, чтобы можно было редактировать документы на любом сервере, не привязывая документ к конкретному серверу.
Продумывал как отдельный Lotus-сервер, и даже Redis...)

При блокировке пишем:
- ID процесса (сгенерирован на конкретной кнопке/агенте и проч.)
- текущий SeqNumber;
- дату (Now);
- статус блокировки = 1.

При разблокировании:
- очищаем ID процесса и дату;
- обновляем SeqNumber до актуального;
- статус блокировки = 0.

Пример:
1. Заблокировали док, прописали текущий SeqNumber = 76.
2. Разблокировали док, обновили SeqNumber = 79 (да, не 77, как должно быть, потому что до меня код писали, видимо, гении...).
3. Пытаемся с другого сервера заблокировать док, - отправляем текущий SeqNumber = 76, а оно не даёт нам заблокировать, т.к. говорит "извини, товарищ, но надо обождать, пока пройдёт репликация"))) На самом деле ничего не говорит, а просто возвращает false, и все изменения записываются в запрос, который отрабатываться агентом по расписанию.

К этому ещё нужно 2 агента:
1. Сбрасывающий блокировку по прошествии определённого времени (например, 1-2 минуты).
2. Удаляющий документ/запись блокировки по прошествии определённого времени с даты последней блокировки (например, месяца 3), - когда док ушёл в архив и больше не меняется. Если вдруг док снова изменится, то запись снова появится.

Короче, как-то так.

Ребята, может уже кто-то делал такое и наступал на грабли (нагрузка, скорость и т.п.)? Не стесняйтесь поделиться опытом!)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 978
611
BIT
393
Появилась идея вынести блокировки в какое-то централизованное место, чтобы можно было редактировать документы на любом сервере, не привязывая документ к конкретному серверу.
Продумывал как отдельный Lotus-сервер, и даже Redis...)

При блокировке пишем:
- ID процесса (сгенерирован на конкретной кнопке/агенте и проч.)
- текущий SeqNumber;
- дату (Now);
- статус блокировки = 1.

При разблокировании:
- очищаем ID процесса и дату;
- обновляем SeqNumber до актуального;
- статус блокировки = 0.

Пример:
1. Заблокировали док, прописали текущий SeqNumber = 76.
2. Разблокировали док, обновили SeqNumber = 79 (да, не 77, как должно быть, потому что до меня код писали, видимо, гении...).
3. Пытаемся с другого сервера заблокировать док, - отправляем текущий SeqNumber = 76, а оно не даёт нам заблокировать, т.к. говорит "извини, товарищ, но надо обождать, пока пройдёт репликация"))) На самом деле ничего не говорит, а просто возвращает false, и все изменения записываются в запрос, который отрабатываться агентом по расписанию.

К этому ещё нужно 2 агента:
1. Сбрасывающий блокировку по прошествии определённого времени (например, 1-2 минуты).
2. Удаляющий документ/запись блокировки по прошествии определённого времени с даты последней блокировки (например, месяца 3), - когда док ушёл в архив и больше не меняется. Если вдруг док снова изменится, то запись снова появится.

Короче, как-то так.

Ребята, может уже кто-то делал такое и наступал на грабли (нагрузка, скорость и т.п.)? Не стесняйтесь поделиться опытом!)
заносим юнид в очередь, при открытии - ищем в очереди, при закрытии - удаляем
очередь - на чём удобно
 

VladSh

начинающий
Lotus Team
11.12.2009
1 794
158
BIT
199
заносим юнид в очередь, при открытии - ищем в очереди, при закрытии - удаляем
Думаю, что если удалять, то мы не получим анализа SeqNumber, и в распределённой среде, где около десятка серверов, потенциально заработаем конфликты.

У вас есть опыт блокировках не очередях? Поделись!)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 978
611
BIT
393
Думаю, что если удалять, то мы не получим анализа SeqNumber, и в распределённой среде, где около десятка серверов, потенциально заработаем конфликты.

У вас есть опыт блокировках не очередях? Поделись!)
не недошли руки :(
 

rinsk

Lotus Team
12.11.2009
1 155
126
BIT
36
Появилась идея вынести блокировки в какое-то централизованное место, чтобы можно было редактировать документы на любом сервере, не привязывая документ к конкретному серверу.
Продумывал как отдельный Lotus-сервер, и даже Redis...)

При блокировке пишем:
- ID процесса (сгенерирован на конкретной кнопке/агенте и проч.)
- текущий SeqNumber;
- дату (Now);
- статус блокировки = 1.

При разблокировании:
- очищаем ID процесса и дату;
- обновляем SeqNumber до актуального;
- статус блокировки = 0.

Пример:
1. Заблокировали док, прописали текущий SeqNumber = 76.
2. Разблокировали док, обновили SeqNumber = 79 (да, не 77, как должно быть, потому что до меня код писали, видимо, гении...).
3. Пытаемся с другого сервера заблокировать док, - отправляем текущий SeqNumber = 76, а оно не даёт нам заблокировать, т.к. говорит "извини, товарищ, но надо обождать, пока пройдёт репликация"))) На самом деле ничего не говорит, а просто возвращает false, и все изменения записываются в запрос, который отрабатываться агентом по расписанию.

К этому ещё нужно 2 агента:
1. Сбрасывающий блокировку по прошествии определённого времени (например, 1-2 минуты).
2. Удаляющий документ/запись блокировки по прошествии определённого времени с даты последней блокировки (например, месяца 3), - когда док ушёл в архив и больше не меняется. Если вдруг док снова изменится, то запись снова появится.

Короче, как-то так.

Ребята, может уже кто-то делал такое и наступал на грабли (нагрузка, скорость и т.п.)? Не стесняйтесь поделиться опытом!)
Приклад - чисто http?
 

VladSh

начинающий
Lotus Team
11.12.2009
1 794
158
BIT
199
Приклад - чисто http?
Как раз нет. Обычная нативная приложуха - LS на клиенте и сервере и Java на сервере.
Просто думаю, как ещё сделать централизованную блокировку, если не по http? Лотусовая блокировка работает в пределах кластера только, да и это дополнительные тупняки и иногда дополнительные ошибки.
 

Gandliar

Lotus Team
16.02.2004
564
26
BIT
110
Мой вариант - база для блокировок на отдельном серваке, общая для всех.
а) пытаюсь сохранить блокировочный в этой базе док с унидом блокируемого, если сохранился - значит заблокировался, если нет - значит кто то успел раньше, находим если надо по униду, кто.
б) разблокировать нашел по униду док и удалил
 

VladSh

начинающий
Lotus Team
11.12.2009
1 794
158
BIT
199
Мой вариант - база для блокировок на отдельном серваке, общая для всех.
а) пытаюсь сохранить блокировочный в этой базе док с унидом блокируемого, если сохранился - значит заблокировался, если нет - значит кто то успел раньше, находим если надо по униду, кто.
б) разблокировать нашел по униду док и удалил
Это так все делают на начальном этапе. И тут же возникают вопросы... Прямой доступ к другому серверу - это очень плохо, - писал выше, - это сильно увеличивает время блокировки/разблокировки и чревато многими ошибками, как-то отвалившейся сетью и т.п. Когда сервер не в доступе (пропала связь), то это решение приведёт к тому, что парализует работу других, зависящих от него серверов.
Для промышленного использования в условиях распределённой сети это решение не годится. Оно плохо даже если сервера в одной локальной сети.
Почему у меня мысли и возникли о блокировке по http.
В моём предложении точно также пытаемся сохранить документ.
Но не с его UNID'ом, а со сгенерированным UNID'ом по параметрам. Путь к базе или код реплики тоже должен там участвовать, т.к. бывают случаи, что часть архивации выполнилась, и док был скопирован в архивную базу, но по какой-то причине процесс не завершился, т.е. возможно изменение документов в разных базах (например при синхронизации списка читателей и т.д.).
И блокировочный док не удаляется из базы. Видимо никто не понял идеи с SeqNumber, раз уже второе такое предложение возникает... И вообще, это не очень хорошая идея сначала создавать документ с определённым UNID, потом удалять его, а потом создавать снова с тем же UNID, так можно нарваться на такую ситуацию, что и заблокировать док не сможешь до удаления deletion-stub'а...
 

savl

Lotus Team
28.10.2011
2 621
314
BIT
466
интересный вариант...
у нас простая блокировка, в пределах сервера, но база отдельная. При разблокировке проверяется время модификации документов.
Блокировки только в UI, при обработке задач не используются, распределёнки нет, поэтому данный вариант подходит, ну правда кластер есть.

Что касается общей идеи:
@VladSh
если блокировка в http, то как бы сервис должен быть единым для всех, так? значит даже в условиях распределенки это как-то надо будет синхронизировать.
И тут я соглашусь с @lmike не надо это в Domino: mq или что там еще, хоть вебсферу ту же, сам "механизм" на другой технологии, хоть C/C++/Go, да даже python.
Вон NATS появился.
Вызвать что-то из Domino становится легче, а вот что-то создать для внешнего вызова - все так же тяжело.
 

rinsk

Lotus Team
12.11.2009
1 155
126
BIT
36
Как раз нет. Обычная нативная приложуха - LS на клиенте и сервере и Java на сервере.
Просто думаю, как ещё сделать централизованную блокировку, если не по http? Лотусовая блокировка работает в пределах кластера только, да и это дополнительные тупняки и иногда дополнительные ошибки.
Отработана реализация блокировок по http для http приложений.
там цимус в том что при умирании\закрытия почти гарантированно отрабатывает метод браузера navigator.sendBeacon...
это можно сделать на и на delete\terminate класса\агента.
+ есть таймер на обновление блокировки раз в 15-30 сек.
если нет изменения статуса блокировки, то оно считается протухшим. + глобальный статус протухания через 1,2,х часов...
Никакие вьюшки при этом не юзаются. Получается хеш от объекта блокировки для создания дока блокировки с unid от хеша объекта для бд кластера.
Для нативного приложения так же это можно реализовать через http в кластере например.
т е фронт сервера изолируется через Nginx например, в котором перечислены нужные члены кластер (для надежности)
в части апстрима примерно так :
upstream lockhost {
server 10.3.224.179:8585 backup;
server 10.3.224.178:80 ;
}
т е - если рухнет один севак то отработает второй ну и т.п.
 

rinsk

Lotus Team
12.11.2009
1 155
126
BIT
36
интересный вариант...
у нас простая блокировка, в пределах сервера, но база отдельная. При разблокировке проверяется время модификации документов.
Блокировки только в UI, при обработке задач не используются, распределёнки нет, поэтому данный вариант подходит, ну правда кластер есть.

Что касается общей идеи:
@VladSh
если блокировка в http, то как бы сервис должен быть единым для всех, так? значит даже в условиях распределенки это как-то надо будет синхронизировать.
И тут я соглашусь с @lmike не надо это в Domino: mq или что там еще, хоть вебсферу ту же, сам "механизм" на другой технологии, хоть C/C++/Go, да даже python.
Вон NATS появился.
Вызвать что-то из Domino становится легче, а вот что-то создать для внешнего вызова - все так же тяжело.
те же яйца вид сбоку...
т е - один фиг нужно точку отказа резервировать...
 

Gandliar

Lotus Team
16.02.2004
564
26
BIT
110
Это так все делают на начальном этапе. И тут же возникают вопросы... Прямой доступ к другому серверу - это очень плохо, - писал выше, - это сильно увеличивает время блокировки/разблокировки и чревато многими ошибками, как-то отвалившейся сетью и т.п. Когда сервер не в доступе (пропала связь), то это решение приведёт к тому, что парализует работу других, зависящих от него серверов.
Для промышленного использования в условиях распределённой сети это решение не годится. Оно плохо даже если сервера в одной локальной сети.
Почему у меня мысли и возникли о блокировке по http.
В моём предложении точно также пытаемся сохранить документ.
Но не с его UNID'ом, а со сгенерированным UNID'ом по параметрам. Путь к базе или код реплики тоже должен там участвовать, т.к. бывают случаи, что часть архивации выполнилась, и док был скопирован в архивную базу, но по какой-то причине процесс не завершился, т.е. возможно изменение документов в разных базах (например при синхронизации списка читателей и т.д.).
И блокировочный док не удаляется из базы. Видимо никто не понял идеи с SeqNumber, раз уже второе такое предложение возникает... И вообще, это не очень хорошая идея сначала создавать документ с определённым UNID, потом удалять его, а потом создавать снова с тем же UNID, так можно нарваться на такую ситуацию, что и заблокировать док не сможешь до удаления deletion-stub'а...

Еще раз поясню принцип.

1. Есть документ, который надо заблокировать. У этого документа есть unid.
2. В отдельной базе блокировок создаем блокировочный док в памяти, задаем ему unid из пункта 1 и пытаемся сохранить.
3. В базе нельзя сохранить 2 дока с одинаковым унидом, соответственно сохранили - значит заблокировали, нет - значит заблокировал кто то другой.
4. Разблокировка - удаляем блокировочный документ хард делитом, без делишен стаба.

Альтернативная идея, похожая на hhtp подход - блокировку производить вызовом агента из блокировочной базы, в него передавать док с параметрами.
В агенте использовать функции lock для исключения одновременной работы агентов, тогда можно записывать блокировочные доки, не удалять их, освобождать, искать по виду

Но первый вариант будет работать параллельно, 1 вид для админа, все поиски по getdocumentbyunid, минимальное количесто полей и работает шустро.


Если, что крайне мало вероятно, сервер, на котором лежит блокировочная база, упадет надолго, то в настроечной базе админ переключит блокировки на другой сервер.
Неясно, чем http лучше чем обычный вызов текущего или другого сервера из скрипта. Если у вас пропадает связь то и http не поможет.
У меня не было проблем вызвать другой сервер. Не очень понятно откуда увеличение времени на блокировку, за какое время происходит блокировка, в милисекундах?
 

rinsk

Lotus Team
12.11.2009
1 155
126
BIT
36
Еще раз поясню принцип.

1. Есть документ, который надо заблокировать. У этого документа есть unid.
2. В отдельной базе блокировок создаем блокировочный док в памяти, задаем ему unid из пункта 1 и пытаемся сохранить.
3. В базе нельзя сохранить 2 дока с одинаковым унидом, соответственно сохранили - значит заблокировали, нет - значит заблокировал кто то другой.
4. Разблокировка - удаляем блокировочный документ хард делитом, без делишен стаба.

Альтернативная идея, похожая на hhtp подход - блокировку производить вызовом агента из блокировочной базы, в него передавать док с параметрами.
В агенте использовать функции lock для исключения одновременной работы агентов, тогда можно записывать блокировочные доки, не удалять их, освобождать, искать по виду

Но первый вариант будет работать параллельно, 1 вид для админа, все поиски по getdocumentbyunid, минимальное количесто полей и работает шустро.


Если, что крайне мало вероятно, сервер, на котором лежит блокировочная база, упадет надолго, то в настроечной базе админ переключит блокировки на другой сервер.
Неясно, чем http лучше чем обычный вызов текущего или другого сервера из скрипта. Если у вас пропадает связь то и http не поможет.
У меня не было проблем вызвать другой сервер. Не очень понятно откуда увеличение времени на блокировку, за какое время происходит блокировка, в милисекундах?
в нативном клиенте проблематично сделать надежный таймер вызова агента для обновления статуса блокировки. если только на JS.
Кстати - должен в форме лотус клиета работать и JS трюк с картинкой - <img src=" &param"/>
 

Gandliar

Lotus Team
16.02.2004
564
26
BIT
110
в нативном клиенте проблематично сделать надежный таймер вызова агента для обновления статуса блокировки. если только на JS.
Кстати - должен в форме лотус клиета работать и JS трюк с картинкой - <img src=" &param"/>
Вот тут непонятно о чем идет речь
 

Gandliar

Lotus Team
16.02.2004
564
26
BIT
110
Ну у нас сделана кнопка "Заблокировать", после чего документ переоткрывается и доступны действия с заблокированным документом. По выходу - разблокируется.
 

rinsk

Lotus Team
12.11.2009
1 155
126
BIT
36
Ну у нас сделана кнопка "Заблокировать", после чего документ переоткрывается и доступны действия с заблокированным документом. По выходу - разблокируется.
А если клиент рухнет - как скоро для других блокировка считается протухшей ?
 

Gandliar

Lotus Team
16.02.2004
564
26
BIT
110
Если рухнет - заводят тикет в тп, тп разбирается и разблокирует.
Тикетов в месяц таких довольно мало, программы работают стабильно.

Причем большей частью обращаются те, у кого что то рухнуло. Заодно и выясняем и ликвидируем причину, чтобы не рушилось потом.
Думаю как то апгрейдить скрипт блокировки, чтобы пользователь на одном и том же устройстве после перезагрузки лотуса после падения мог бы заблокировать документ который был заблокирован им до падения.
Тут надо придумать, либо в нотес ини сгенерить пользователю уникальный ключик и потом писать его в док блокировки, либо в нотес ини писать/стирать униды блокируемых доков.
Наверное первый вариант универсальнее.
 
Последнее редактирование:

Mikle_GB

Lotus Team
07.07.2016
70
25
BIT
61
1) А что, в новых версиях сервера встроенная блокировка всё ещё тупит? На 8.5 точно тупила, а на 10/11/12?
2) Нужна единая блокировка на нескольких кластерах? а зачем, собсно? и сколько у вас кластеров, в чём проблема растиражировать "внутрикластерное" решение?
Для блокировок в пределах кластера - кмк, это нормальное ограничение - вполне достаточно базы с блокировками, как собсно все и делают. Это и есть централизованное место, надёжное как сам кластер:) Видов нету, поиск по юнид - очевидные пути для ускорения доступа. В базе блокировок агент по расписанию ищет непристойно долгие блокировки и либо тупо их чистит, либо просит админов разобраться. Создавать доки можно как хочешь - хоть хттп, хоть скрипт, хоть джава.
В общем, проблема кажется несколько надуманной:)
 

Gandliar

Lotus Team
16.02.2004
564
26
BIT
110
Непонятно что такое кмк.

Вот уточните по поводу кластеров и блокировок.

Есть кластер из двух серверов,
Бывает 2 случая
а) второй сервер кластера недоступен для пользователей и на него переключаются вручную при обслуживании или падении первого.
б) оба сервера кластера доступны одновременно да пользователей

В случае а) база блокировок может быть на каждом из серверов и используется только на том на котором пользователи.
В случае б) база блокировок должна быть на стороннем сервере

в случае блокировок на стороннем сервере их тоже надо как то резервировать и обеспечить массовое переключение всех баз на новую базу, авто или вручную
И еще сервера кластера находятся в разных цодах
И пользователи тоже находятся в разных территориальных локациях

Задача стоит

1. обеспечить параллельную работу обоих серверов кластера
2. пользователи подключаются к ближайшему серверу из кластера
3. при этом блокировка общая для обоих серверов кластера
4. недоступность одного из серверов кластера не должна приводить к остановке работы
5. механизм блокирования тоже как то должен резервироваться и желательно автоматически

Каковы могут быть реализации?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!