gifts2017

Неожиданное поведение бизнес-процесса 1С 8.2

Опубликовал yares в раздел Программирование - Практика программирования

Всегда ли поведение бизнес-процесса, созданного на платформе 1С:Предприятие 8 определяется схемой, заложенной разработчиком, или иногда в него могут вмешаться «потусторонние силы»?  Об этом пойдет речь в статье.

В официальной документации по платформе 1С:Предприятие 8.2  в разделе «13.7. Разделение и слияние» поведение бизнес-процесса в точках разделения и слияния описано так:

«Для разделения бизнес-процесса на несколько параллельно (одновременно и независимо) исполняемых ветвей используется точка разделения. Точка разделения имеет один вход и неограниченное количество выходов.

Для синхронизации разделенных ранее ветвей используется точка слияния. Бизнес-процесс не будет выполняться дальше точки слияния, пока все входящие в нее ветви не будут пройдены.»

Продемонстрирую это на примере простой карты маршрута (рис.1)

 Рисунок 1

Рисунок 1

 

В точке разделения создаются задачи в каждой из ветвей (рис.2),  далее каждая ветвь выполняется параллельно, а задача в точке Действие4 будет создана тогда, когда будут выполнены все задачи каждой ветви (рис.3)

 Рисунок 2

Рисунок 2

Рисунок 3

Рисунок 3

 

Всегда ли система ведет себя подобным образом. Давайте выясним. Для начала обратим внимание на то, в какой последовательности создаются задачи после точки разделения (рис.4)

 Рисунок 4

Рисунок 4

 

По номеру задачи можно увидеть, что первой была создана задача в точке Действие3. Теперь в модуле бизнес-процесса для этой точки опишем следующий обработчик при создании задач:

Процедура Действие3ПриСозданииЗадач(ТочкаМаршрутаБизнесПроцесса, ФормируемыеЗадачи, Отказ)

      Для каждого ЗадачаОбъект Из ФормируемыеЗадачи Цикл

            ЗадачаОбъект.ВыполнитьЗадачу();

      КонецЦикла;

КонецПроцедуры

Такой обработчик приведет к тому, что создаваемая задача сразу будет выполнена. Стартуем новый бизнес-процесс с картой маршрута, приведенной на рис.1. И что мы увидим?  После выполнения задачи Действие3 была создана задача Действие4 (рис.5), несмотря на то, что другие ветви процесса еще не выполнены! Тех, кто попытается воспроизвести указанную ситуацию, предупреждаю: у вас вместо написания обработчика для точки Действие3 может оказаться необходимым написать обработчик автовыполнения задачи для точки Действие1 или Действие2. Точка действия, автовыполнение которой "ломает" схему процесса - это именно та точка, в которой создается первая задача после точки разделения. От чего зависит последовательность создания задач, будет рассмотрено ниже.

 Рисунок 5

Рисунок 5

 

Далее выполним задачу Действие4 и убедимся, что процесс идет дальше, не дожидаясь завершения задач в точках Действие1 и Действие2 (рис.6)!

 Рисунок 6

Рисунок 6

 Далее, когда выполним задачи Действие1 и Действие2, снова создается задача Действие4 (рис.7).

Рисунок 7

Рисунок 7

Такого поведения  простой схемы маршрута никак нельзя предположить, исходя из приведенного в начале статьи описания.  Может это какая-то ошибка отображения схемы?  Нет, на самом деле все так и происходит. Бизнес-процесс не только выполняется дальше точки слияния, не ожидая завершения задач в параллельных ветвях, но и создает повторно задачи в точках маршрута, следующих за  точкой слияния после завершения параллельных ветвей . Смотрим список задач по нашему процессу и видим по 2 задачи для точек Действие4 и Действие5 (рис.8)

Рисунок 8 

Рисунок 8

О чем это говорит? Фактически это означает, что при автоматическом выполнении задачи Действие3 мы получим поведение бизнес-процесса, соответствующее схеме, приведенной на рисунке 9, то есть точка слияния при выполнении одной ветви пропускается. Но это тоже не всегда верно. Если в точке Действие4 мы не будем выполнять первую из созданных задач, до появления второй задачи в результате выполнения параллельных ветвей до точки слияния, то следующая задача в точке Действие5 будет создана только при выполнении обеих задач в точке Действие4, то есть бизнес-процесс как бы исправляет допущенную ранее ошибку игнорирования точки слияния. Далее по схеме маршрута будет создаваться только по одной задаче. Тем, кого заинтересовало такое поведение бизнес-процесса, предлагаю убедиться в этом самостоятельно.

Рисунок 9

Рисунок 9

Рассмотрим другой пример. Предположим, что точка Действие3 является не точкой действия, а точкой вложенного процесса. Для простоты используем следующую схему вложенного бизнес-процесса (рис.10)

 Рисунок 10

Рисунок 10

Если в событии Условие1ПроверкаУсловия ничего не выполнять, такой процесс завершается сразу после старта, не создавая ни одной задачи. На практике такое может встретиться и в более сложных процессах, если необходимость выполнения задач процесса возникает только при выполнении каких-то условий. Заменим точку Действие3 точкой вложенного бизнес-процесса и получим схему, приведенную на рисунке 11.

 Рисунок 11

Рисунок 11

Проверяем работу бизнес-процесса со вложенным процессом и убеждаемся в аналогичном поведении. На рисунке 12 – схема бизнес-процесса после старта.

 Рисунок 12

Рисунок 12

Всегда ли проявляется такое поведение в подобных схемах? Давайте разберемся. Обратим внимание на то, что задачи в точке разделения создаются в том порядке, в каком были добавлены линии в точке разделения. Это можно увидеть, если вывести имена соединительных линий (рис.13).

 Рисунок 13

Рисунок 13

Попробуем поменять местами Линия2 и Линия4. И наконец-то при старте нового процесса мы видим ожидаемый результат (рис.14)

 Рисунок 14

Рисунок 14

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

Делаем вывод:

При автоматическом выполнении задачи, привязанной к первой по порядку добавления линии точки разделения, если после этой задачи сразу следует точка слияния, эта точка слияния игнорируется и создается следующая по схеме маршрута задача. Если не обращать внимания на последовательность связей, можно при создании внешне одинаковых схем получить разное поведение бизнес-процесса.

Эту зависимость следует учитывать и при доработке существующих схем. Допустим, мы решили, что вместо одной задачи в точке Действие1 на рисунке 14, которая у нас начала работать так, как требуется, должен быть вложенный процесс, который при определенных условиях, может выполниться автоматически по условию аналогично рисунку 10. Тогда при старте нашего процесса мы увидим знакомую картину с игнорированием точки слияния (рис.15)

 Рисунок 15

Рисунок 15

В заключение отмечу, что указанное поведение бизнес-процессов было замечено еще на платформе 8.1 и продолжает проявляться на последних релизах 8.2. При подготовке статьи тестирование выполнялось на релизе платформы 8.2.15.310.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. mosAdm (mosAdm) 04.10.12 13:56
Не вдаваясь глубоко в теорию и исследования открыл типовое закрытие месяца в УПП, то которым пользуются куча народа и нет никаких неожиданностей все работает и вроде жалоб не слышно. Может дело только в одном после точки слияния установлена точка разделения.
А "неожиданное" поведение это "особенность" которую надо учитывать.
Прикрепленные файлы:
2. Александр Капустин (kapustinag) 04.10.12 21:47
(1) mosAdm, Если задачу выполняет человек, то, конечно, никаких проблем, описанных в статье, не будет. В статье описаны проблемы, которые могут возникнуть, если некоторые задачи выполняются автоматически. Так как человек выполнит свою задачу хотя бы на секунду позже, чем созданы все параллельные задачи, то все будет, как описано в документации по бизнес-процессам.
3. KV1s (KroVladS) 09.10.12 10:07
Всплывают аналогичные проблеммы, буду копать.
4. Евгений Чернета (nl8) 11.10.12 10:11
Я правильно понял, что способ обхода ошибки - это потенциально автоматически завершаемую задачу (или вложенный БП) не присоединять к первой линии, исходящей из точки разделения?
А если у нас все выходящие из точки разделения задачи - потенциально автоматически завершаемые, то стоит задуматься о переделке карты маршрута и/или логики БП, так?
5. Эстер Коган (e.kogan) 11.10.12 14:57
Отличная статья, с большим удовольствием плюсую. В кой-то веки нетривиальная.
Anikrion; +1 Ответить
6. Dimon (klel) 11.10.12 20:42
Хорошая статься, много описания и картинки :) что не мало важно для простого обывателя =)
7. yares 11.10.12 21:48
(4) nl8, да, проверяем условия автовыполнения всех ветвей, к первой исходящей из точки разделения линии присоединяем ветвь, которая всегда будет выполняться только интерактивно. Если возможно автовыполнение любой ветви, меняем схему.
8. Максим Кузнецов (Makushimo) 12.10.12 06:25
На редкость понятное и подробное описание.
С большим удовольствием прочитал.
Плюсую.
Anikrion; +1 Ответить
9. yares 12.10.12 09:44
(1) mosAdm,
В конфигурации УПП задачи закрытия месяца должны выполняться пользователями интерактивно. Если мы попытаемся автоматизировать выполнение задач процесса при условии наличия корректно проведенных документов, то при автовыполнении задачи в точке маршрута ПогаситьСтоимостьСпецодежды получим описанную в статье ситуацию. Автовыполнение задач других ветвей после точки разделения не вызывает проблем. Для воспроизведения проблемы использовал демо-базу УПП 1.3.30.2 с внесенными доработками для автовыполнения задач. Релиз платформы – 8.2.16.368.
Прикрепленные файлы:
10. mosAdm (mosAdm) 12.10.12 13:58
(9) Абсолютно с Вами согласен, один человек всегда может найти способ сломать работу другого :-)
11. Владимир Клименко (KliMich) 14.10.12 03:35
Спасибо за статью. Попробую применить на практику
12. Антон Тоник (artichoke) 14.10.12 14:22
Хорошая статья, всё есть - выявление потенциальной проблемы, описание неоднозначных вариантов решения, предложение однозначного решения (+ достаточное количество иллюстраций)!
13. Anikrion (Anikrion) 09.10.14 13:53
Спасибо большое, очень полезная статья
14. Алексей (alexqc) 08.12.14 11:55
Читаем СП:

ПриСозданииЗадач (OnCreateTask)
...
Описание:

Возникает после выполнения стандартной или переопределенной в обработчике события ПередСозданиемЗадач механики генерации списка задач. Обработчик этого события может "донастроить" автоматически сформированные задачи или удалить некоторые из них, а также добавить к ним новые задачи.
Запись списка задач будет осуществлена после завершения обработчика.



То есть: в момент ПриСозданииЗадач задачи еще не записаны. При этом выполнение задачи вызывает ее запись. Таким образом обработчик нарушает логику БП: происходит запись и выполнение задачи, пока еще не записаны остальные. Отсюда выводы:

1. Не желательно делать подобные операции в ПриСозданииЗадач (он предназначен для настройки задач, а не для выполнения). Вместо автовыполнения можно использовать точки вида Обработка, а не Действие.

2. Если очень хочется, то можно: поскольку проблема в том что происходит выполнение задачи ДО записи остальных - надо сделать чтобы остальные тоже были записаны! То есть: делаем 2 цикла, в первом - записываем задачи, во втором - выполняем.

sulfur17; gaabora; k4rimov; +3 Ответить
15. silwendil silwendil (silwendil) 03.06.15 17:57
В 8.2 проблема решалась добавлением дополнительной ветки с минимальным порядковым номером и задачей, которая никогда не автовыполнялась.
Но вот пришло время переползать на 8.3, теперь этот механизм совсем испортился, процесс вообще не ждёт выполнения задач в параллели. Выполнение любой из задач приводит к выходу за точку слияния. Остальные задачи потом ведут себя так же. То есть, сколько задач в параллели, столько раз процесс пройдёт через точку слияния. Полный хаос получается.
Есть какое-то системное решение? Или придётся эмулировать ожидание выполнения всех задач? Например, добавлять перед слиянием задачу таймера, которую нельзя выполнить, пока не выполнены остальные задачи? Платформа 8.3.6.2014

UPD Нашел источник проблемы. Когда карта достаточно сильно разрастается (~100 точек и более) при сохранении появляется ошибка примерно такого содержания: "Проверка карты маршрута не выполнена, потому что она слишком сложная". После этого конфигурация успешно сохраняется, но механизм слияния перестаёт работать совсем. Пришлось его эмулировать. Перед слиянием поставил еще одну точку и повесил задачу на таймер, в "ПередВыполнением" поставил отказ, если есть невыполненная задача хоть в одной из веток. Все ветки сливаются в эту точку, а уже она идёт к слиянию.
16. Денис Аграновский (de0nis) 25.08.16 22:41
Столкнулся с подобной проблемой на 8.2. часть схемы аналогична рисунку 11, при этом все задачи могут авто выполняться. Сделал два решения:

1. В данной задаче позволяло, вместо авто выполнения просто пропустить задачи.
Процедура Задача1ПриСозданииЗадач(ТочкаМаршрутаБизнесПроцесса, ФормируемыеЗадачи, Отказ)
	
Если АвтоВыполнение() Тогда 
	ФормируемыеЗадачи.Очистить();	
КонецЕсли;
		
КонецПроцедуры    
...Показать Скрыть

При этом задачи с авто выполнением просто не формируются, а задача с бизнес процессом выполнялась последней. В данном случае слияние отработало корректно.

2. Задачу - вложенный БП - заменил обычной задачей (см. закрытие месяца задачу Расчет НДС), а условие, приводящее к автоматическому завершению вложенного БП перенес в ПриФормированииЗадач, если оно не выполнялось, то стартовал вложенный БП и в нем создавались задачи, если выполнялось, создавалась простая задача никому не адресованная.
Процедура СоздатьКонтрагентаПриСозданииЗадач(ТочкаМаршрутаБизнесПроцесса, ФормируемыеЗадачи, Отказ)
	СтрокаОперации = Операции.Найти(ТочкаМаршрутаБизнесПроцесса);		
	Если Не СтрокаОперации = Неопределено И СтрокаОперации.Использовать Тогда 
		СтартоватьПодчиненныйБизнесПроцессСоздатьКонтрагента(ФормируемыеЗадачи[0]);
	Иначе
		// Создаём обычную задачу. Что БП дождался точки слияния.
		ФормируемыеЗадачи[0].Наименование = ФормируемыеЗадачи[0].Наименование +"##Служебная##";
	КонецЕсли;	
...Показать Скрыть

Далее по порядку формировались остальные задачи и при формировании последней по порядку проверлось если вложенный БП у первой, если его не было, то эта задача автоматически завершалась, только не методом ВыполнитьЗадачу() - он так же приводил к созданию следующей за слиянием задачи, а через Задача.Выполнена = Истина.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа