Очередной "мягкий" отключатель активных и не очень пользователей

Тема отключения пользователей не нова, но это чуть другой взгляд на проблему.

Поставлено ТЗ написания как можно более простого метода, чтобы "мягко" отключать пользователей. Базы как клиент-серверные, так и файловые. И отключать надо по команде, а не каждую сессию отдельно руками.
Концепция решения "мягкого" отключения следующая — пользователь должен "сам" завершить свою работу. Иными словами необходимо дать клиенту понять, что необходимо завершить работу. Вариаций можно добавить сколько угодно.

Для этого была написана админовская часть, использующая некую табличную часть сеансов, получающая сеансы с АГЕНТА для клиент-серверных баз, так и  с файловых баз, используя механизм COM(медленный) или HTTP-сервисы(быстрый, предпочтительно), с функцией отключения нужного сеанса:

Процедура ДатьЗаданиеНаОтключениеСеансовИБ(ИБ, ИмяПользователя, НомерСеанса, ИмяПриложения, Компьютер, СообщениеПользователю = "", ТаймАут=10) Экспорт
// Сеанс.ИмяПриложения
//1CV8 - идентификатор приложения 1С:Предприятие в режиме запуска "Толстый клиент";
//1CV8C - идентификатор приложения 1С:Предприятие в режиме запуска "Тонкий клиент";
//WebClient - идентификатор приложения 1С:Предприятие в режиме запуска "Веб-клиент";
//Designer - идентификатор приложения Конфигуратор;
//COMConnection - идентификатор сессии внешнего соединения 1С:Предприятия через COM;
//WSConnection - идентификатор сессии Web-сервиса;
//BackgroundJob - идентификатор сессии обработки заданий;
//SystemBackgroundJob - идентификатор системного фонового задания;
//SrvrConsole - идентификатор сессии консоли кластера;
//COMConsole - идентификатор административной сессии внешнего соединения;
//JobScheduler - идентификатор сессии планировщика заданий;
//Debugger - идентификатор сессии отладчика;
//OpenIDProvider - провайдер OpenID;
//RAS - идентификатор сервера администрирования.

Если ИмяПриложения = "1CV8" или ИмяПриложения = "1CV8C" или ИмяПриложения = "WebClient" или ИмяПриложения = "Толстый клиент" или ИмяПриложения = "Тонкий клиент" или ИмяПриложения = "Веб-клиент" Тогда
КлючОбъекта   = "ЗавершениеРаботы";
КлючНастроек  = СтрЗаменить(Строка(НомерСеанса), Символы.НПП,"");
Настройки   = ИБ.NewObject("Структура");
Настройки.Вставить("Пользователь",    ИмяПользователя);
Настройки.Вставить("ТекущийПользователь",  ПараметрыСеанса.ТекущийПользователь.Наименование);
Настройки.Вставить("Компьютер",     Компьютер);
Настройки.Вставить("Сеанс",      НомерСеанса);
Настройки.Вставить("ДатаИнициацииОтключения", ТекущаяДата());
Настройки.Вставить("ТаймАут",     ТаймАут);
Если НЕ СообщениеПользователю = "" тогда
Настройки.Вставить("РежимОтключения",  2);// 0 - отключение без предупреждения, 1 - вывести с предупреждением , 2 - просто сообщение
Настройки.Вставить("СообщениеПользователю", СообщениеПользователю);
Иначе
Настройки.Вставить("РежимОтключения",  1);// 0 - отключение без предупреждения, 1 - вывести с предупреждением
Настройки.Вставить("СообщениеПользователю", "Сообщение от Админа: ""Просьба выйти из базы для выполнения архивации""");
КонецЕсли;
ОписаниеНастроек  = "Отключение пользователя по запросу администратора";
ИБ.ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, Настройки, ОписаниеНастроек, ИмяПользователя);
КонецЕсли;
КонецПроцедуры

Поскольку почти все клиентские базы стоят на поддержке без возможности вносить изменения, то было написано расширение. В нем присутствует функция оценки задания на отключение. Отключается только необходимый пользователь. По сути дела, решение принимает клиентская часть — "Если МНЕ задание на завершение работы, то будет предпринята попытка отключения". Ниже сама функция отключения

Функция КонтрольЗавершенияРаботы() Экспорт
НомерСеанса   = ЗРП_ОбщийМодульСервер.ПолучитьНомерСеанса();
НачалоРаботы  = ЗРП_ОбщийМодульСервер.ПолучитьдатуСеанса(НомерСеанса);
СтруктураПараметров = ЗРП_ОбщийМодульСервер.ЗагрузитьХранилищеОбщихНастроек("ЗавершениеРаботы", СтрЗаменить(Строка(НомерСеанса),Символы.НПП,""), ИмяПользователя());
Если НЕ СтруктураПараметров = Неопределено Тогда
Если НЕ ЗРП_ОбщийМодульСервер.ЗапущенКонфигуратор() Тогда
Если НомерСеанса = СтруктураПараметров.Сеанс Тогда
ЗРП_ОбщийМодульСервер.УдалитьХранилищеОбщихНастроек("ЗавершениеРаботы", СтрЗаменить(Строка(НомерСеанса),Символы.НПП,""), ИмяПользователя());
Попытка
Если СтруктураПараметров.ДатаИнициацииОтключения > НачалоРаботы Тогда  // если пользователь успел выйти до команды
Если СтруктураПараметров.РежимОтключения = 0 Тогда  // безусловное завершение без вопросов
ЗавершитьРаботуСистемы(Ложь);
ИначеЕсли СтруктураПараметров.РежимОтключения = 1 Тогда // только сообщение с описанием того кто выдал задание на закрытие
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияПредупреждения", ЗРП_ОбщийМодульКлиент);
ПоказатьПредупреждение(Оповещение, СтрЗаменить(СтруктураПараметров.СообщениеПользователю, "%", СтруктураПараметров.ТекущийПользователь), СтруктураПараметров.ТаймАут);
ИначеЕсли СтруктураПараметров.РежимОтключения = 2 Тогда // выдача вопроса с интерактивным выбором ЗАКРЫТЬ или НЕТ
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЗРП_ОбщийМодульКлиент);
Кнопки = Новый СписокЗначений;
Кнопки.Добавить(КодВозвратаДиалога.ОК, "Завершить");
Кнопки.Добавить(КодВозвратаДиалога.Отмена, "Отмена");
ПоказатьВопрос(Оповещение, СтрЗаменить(СтруктураПараметров.СообщениеПользователю, "%", СтруктураПараметров.ТекущийПользователь), Кнопки, СтруктураПараметров.ТаймАут, , "Завершение работы системы");
ИначеЕсли СтруктураПараметров.РежимОтключения = 3 Тогда // только сообщение
Предупреждение(СтруктураПараметров.СообщениеПользователю, СтруктураПараметров.ТаймАут);
КонецЕсли;
КонецЕсли;
Исключение
ЗРП_ОбщийМодульСервер.ЗЖР("ЗавершениеРаботыПользователей.КонтрольЗавершенияРаботы()", "Ошибка",,ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецФункции

Расширение на данный момент работоспособно на версии ЗУП 3.1.11.133, БУХ 3.0.73.60, КА2 2.4.7.141/3.2.23.3(БИТфинанс). Поскольку не использовалось БСП, то и проблем с библиотекой тоже нет.
Остались две проблемы:

1. Разрешимая — условие совместимости, меняемое при обновлении, которое можно исправить в любой момент;
2. Не решённая — если на главном окне вылезло окно с вопросом, блокирующим весь интерфейс, ожидающего интерактивного принятия решения. Поиск решения ведётся.

 

P.S. Сильно прошу палками не кидать. Любые реальные ссылки будут восприняты с благодарностью.

9 Comments

  1. Xershi

    Какое может быть решение, когда пользователь ушел домой. Только рубить.

    А какая цель публикации, академический интерес?

    По поводу расширения. Пишут обработку и она анализирует совместимость и затем ставит нужную версию.

    Reply
  2. ybatiaev

    (1) Если необходимо АВТОМАТИЧЕСКИ обновить базы, без участия программистов, но:

    — база файловая(как можно рубить программно? Научите);

    — необходимо обновить около 500 баз за ночь и ничто не должно помешать;

    — необходимо отключать только те базы, в которых не работают в конфигураторе или отключить по определённому правилу .

    Цель публикации — поделиться опытом.

    По поводу обработки напишите путь решения. Буду признателен. Кроме интерфейса только «Такси» или «Такси. Разрешено..,» есть ещё и совместимость версий.

    Reply
  3. Xershi

    (2) для примера посмотрите как сейчас ставится Битрикс.

    На файловой базе запуск обработки блокировки пользователей, как и в клиент серверной.

    Про 500 баз. Так у вас же расширение, а не конфигурация для обновления.

    Reply
  4. ybatiaev

    (3) про битрикс не понял. В смысле как ставится? Хочу с ним познакомится, но руки не доходят.

    Не понял и про блокировки. К чему Вы это написали? И я про блокировку не писал (моя конфа и это делает при необходимости).

    Про 500 баз — данное расширение помогает выкинуть пользователей без участия программиста… у меня в том числе и конфигурация обновлений.

    Reply
  5. dock

    1) в ЗУП3 и БУХ3 прекрасно отрабатывает и типовой механизм… (в том числе и для файловых баз).

    2) На скрине очень интересное сообщение от админа: «… для выполнения архивации»

    В серверных базах архивация (бекап) выполняется средствами SQL, в файловых базах — специальными утилитами (например cobian backup), посредством теневой копии. В обоих случаях, выгонять пользователей не требуется :).

    Reply
  6. ybatiaev

    (5)

    — «Смешное сообщение» — сделал для теста. Задаётся любое в админовской части.

    — У нас сисадмины отделены от программеров вообще и средствами SQL делается всё с разрезом неделя. Всего неделя. Главная их задача — бесперебойная работа СУБД, скорость и оперативность исправления ошибок;

    — с базами работают и пользователи-администраторы. Других не дёргают. Хранение баз (любой базы) настраиваемое. Без администраторов баз сами базы могут быть восстановлены или сделан срез перед операциями. Таких срезов много и дергать администраторов не разрешают;

    — Восстановление из бакапа SQL процесс более затратный по времени, чем из DT;

    — файловую базы можно просто скопировать, если что, но обновить после этого всё же не удастся, если база залочена. Прошу подсказать типовой программный механизм с файловыми базами, без участия программиста пожалуйста. Направьте, может что упустил. Работы много… всего читать не успеваю.

    Reply
  7. dock

    (6)

    1)

    — Восстановление из бакапа SQL процесс более затратный по времени, чем из DT;

    Если загрузка из DT происходит быстрее, чем загрузка из бекапа SQL…. значит у вас что-то не так с SQL базой 🙂 однозначно!

    Чисто технически, при загрузке из DT, выполняется больше операций 🙂

    2)

    — файловую базы можно просто скопировать, если что, но обновить после этого всё же не удастся, если база залочена.

    просто скопировать, если в базе «сидит» хотя бы один пользователь ? ни разу не получалось «просто скопировать» 🙂

    про «залочена» не понял… залочена средствами 1С или системой ?

    Reply
  8. ybatiaev

    (7) по 1 вопросу — передам сисадминам. Насколько мне известно восстановление с DT «чистит» пустое место и частично восстанавливает «битые» ссылки, если это возможно. С SQL восстанавливается ВСЁ полностью. Поэтому операций да, больше.

    по 2 пункту — да прям. Сейчас проверил, может что изменилось. Открыл и конфигуратор и клиента. *.1CD прекрасно скопировался. И это является стандартным механизмом «бакапа» при автообновления у самих 1С-ников.

    Reply
  9. dock

    (8)

    *.1CD прекрасно скопировался.

    соглашусь, я не прав… Но это уже изменение на уровне самой платформы — раньше была ошибка «файл занят»…

    Всё течёт, все меняется 🙂

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *