Пользовательская задача

Обзор

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

Один исполнитель или группа

В BPMN у задачи может быть только один исполнитель. Когда говорят «задача назначена группе», имеют в виду список потенциальных исполнителей, а не объект UserGroup. Один из них должен стать фактическим исполнителем, забрав задачу.

Графическая нотация

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

user task
XML-представление

В XML пользовательская задача определяется так. Атрибут id обязателен, атрибут name необязателен.

<userTask id="user-task-01" name="User task" />

Свойства

В моделере BPMN можно задать следующие свойства пользовательской задачи:

Свойство

Описание

Id

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

Name

Имя задачи, не более 255 символов. Обычно задачи называют по схеме «глагол + объект», например «Согласовать заказ» или «Отправить счет».

Due date

Дата, к которой задача должна быть выполнена. См. Срок выполнения.

Business calendar name

Бизнес-календарь, по которому рассчитывается срок выполнения. См. Использование бизнес-календаря.

Assignee

Исполнитель задачи или потенциальные исполнители (кандидаты). См. Назначение исполнителя.

Form

Пользовательский интерфейс задачи. См. Процессные формы пользовательской задачи.

Multi instance

См. Множественный экземпляр.

Task listeners

Слушатели, которые срабатывают на события жизненного цикла задачи. См. Настройка слушателей задач.

Notifications

Уведомления, которые отправляются при событиях задачи. См. Уведомления.

Execution listeners

См. Слушатели выполнения.

Extension properties

См. Свойства расширения.

Asynchronous execution

  • Asynchronous

  • Exclusive

  • Asynchronous leave

  • Asynchronous leave exclusive

Начиная с Jmix 3.1

Documentation

См. Документация.

Срок выполнения

Параметр срок выполнения (due date) пользовательской задачи задает крайний срок, к которому задача должна быть выполнена. Этот параметр важен для управления действиями процесса, зависящими от времени.

Срок выполнения сам по себе не запускает никаких автоматических действий. Последующие действия нужно настроить вручную.

Задание срока выполнения

Параметр Due date можно задать двумя способами:

  • Фиксированная дата: дата в будущем, которая означает крайний срок. (Дата в прошлом игнорируется, задача будет показана как просроченная.)

  • Длительность: период времени, отсчитываемый с момента создания задачи.

Фактически срок выполнения — это текстовое поле, которое движок процессов интерпретирует во время выполнения. Доступны следующие варианты:

  • Строка в формате ISO8601, задающая фиксированную дату или длительность.

  • Переменная процесса типа:

    • java.lang.String — должна содержать значение в формате ISO8601.

    • java.util.Date — должна содержать дату.

  • Выражение, которое во время выполнения вычисляется в один из вариантов выше, например $/{someDateVariable/}.

  • Если значение переменной равно null, ошибки не возникает. Это означает, что у задачи нет крайнего срока.

  • Параметр Due date не проверяется при развертывании процесса. Но во время выполнения неверное значение вызовет ошибку.

Примеры ISO 8601

  • Фиксированная дата:

    • 2024-02-01T08:40:37

    • 2050-01-01

  • Длительность:

    • PT20M — через 20 минут

    • PT5H — через 5 часов

    • PT3D — через 3 дня

Работа со сроком выполнения из кода

Параметром due date можно управлять с помощью методов класса Task:

Task task = taskService.createTaskQuery()
                .taskId("taskId").singleResult(); (1)
task.getDueDate(); (2)
task.setDueDate(null); (3)
taskService.saveTask(task); (4)
1 получение задачи по id
2 получение текущего срока выполнения
3 установка нового срока выполнения, равного null
4 сохранение объекта задачи

Так можно динамически менять сроки выполнения в зависимости от бизнес-логики. Например, исполнитель может попросить дополнительное время на выполнение задачи.

Использование бизнес-календаря

Если установлено дополнение Business Calendars, в разделе свойств General на экране Web BPM Modeler появляется поле бизнес-календаря:

busines calendar

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

Например, пользователь получил задачу в 16:00. В бизнес-календаре стандартное рабочее время — с 10:00 до 18:00, а срок выполнения задан как 3 часа (PT3H).

Крайний срок будет не в 19:00, через 3 часа, а в 11:00 следующего рабочего дня. С бизнес-календарем учитываются только рабочие часы.

С бизнес-календарем длительность можно задать в часах и минутах, но не в днях.

XML-представление Пользовательская задача со сроком выполнения:

<userTask id="Activity_0gsy9yk" name="User task"
    flowable:dueDate="PT3H" (1)
    flowable:businessCalendarName="test-calendar"> (2)
. . .
</userTask>
1 срок выполнения в виде длительности
2 атрибут бизнес-календаря

Подробнее см. в описании дополнения Business Calendars.

Назначение исполнителя

Чтобы задачу можно было выполнить, ей нужно назначить исполнителя. Исполнителем задачи может быть назначен только один пользователь, его называют assignee.

Атрибут assignee может быть пустым. Это значит, что ни у одного пользователя эта задача не отображается в списке задач. Обычно такая задача считается групповой: у нее есть список потенциальных исполнителей, или кандидатов. Кроме того, исполнителя можно назначить во время выполнения — с помощью административных функций или из кода.

Источники исполнителя

В Jmix BPM источник исполнителя (assignee source) — это способ, которым определяется пользователь, назначаемый исполнителем конкретной пользовательской задачи в бизнес-процессе. Есть три варианта:

Expression

Выражение, результат которого — строка с именем пользователя.

Process variable

Переменная, которая ссылается на сущность User.

User provider

Java-класс с методом, который возвращает имя пользователя.

assignee sources

Назначение задачи по выражению

Выражение — источник исполнителя по умолчанию. Нужно написать выражение, которое вычисляет имя пользователя-исполнителя. Например, если сущность User хранится в переменной процесса manager, выражение будет таким: ${manager.username}:

assign by expression

XML-представление

<userTask id="user-task-01" name="User task"
    flowable:assignee="${manager.username}"
    jmix:assigneeSource="expression"
    jmix:assigneeValue="${manager.username}" />

Чтобы назначить задачу конкретному пользователю, можно указать имя пользователя напрямую:

assigne by expression direct

Также можно вызвать метод бина Spring, который возвращает имя пользователя:

${smpl_MyBean.evaluateManager(methodParam1, 'methodParam2')}

Назначение задачи по переменной процесса

Если выбрать источник исполнителя Process variable, на панели свойств появляется компонент ComboBox. В нем отображаются поля и переменные процесса типа Entity, класс сущности которых реализует интерфейс UserDetails.

Встроенная переменная initiator

При моделировании процесса для назначения задач доступна встроенная переменная процесса initiator. Она содержит сущность пользователя, который запустил процесс:

assignee initiator

XML-представление

Пользовательская задача с исполнителем, назначенным по переменной процесса:

<userTask id="user-task-01" name="User task"
    camunda:assignee="${initiator.username}"
    jmix:assigneeSource="processVariable"
    jmix:assigneeValue="initiator" />

Если процесс запущен через API или сообщением либо сигналом, переменная initiator не определена. Ее использование может вызвать ошибку во время выполнения.

Переменную процесса initiator можно отключить с помощью следующего свойства:

jmix.bpm.process-initiator-variable-enabled=false

Также можно изменить имя переменной initiator:

jmix.bpm.process-initiator-variable-name=manager

Назначение задачи через поставщика пользователей

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

selecting user provider

Класс поставщика пользователей должен реализовать один или несколько методов, возвращающих String. Метод получает значения параметров, заданные в моделере, и возвращает имя пользователя, который становится исполнителем задачи.

XML-представление

Пользовательская задача с исполнителем, назначенным через поставщика пользователей:

<userTask id="user-task" name="User task" jmix:assigneeSource="userProvider" jmix:assigneeValue="smpl_MyUserProvider">
  <extensionElements>
    <jmix:springBean beanName="smpl_MyUserProvider" methodName="getUser" />
  </extensionElements>
</userTask>

Класс поставщика пользователей — это обычный бин Spring с аннотацией @UserProvider. Вот пример поставщика пользователей, который читает переменную процесса с адресом электронной почты пользователя и находит пользователя в базе данных.

@UserProvider(value = "smpl_MyUserProvider", description = "Returns a user with the specified email")
public class MyUserProvider {

    @Autowired
    private DataManager dataManager;

    public String getUserByEmail(String parameter) {
        return dataManager.load(User.class)
                .query("select u from smpl_User u where u.email = :email")
                .parameter("email", parameter)
                .one()
                .getUsername();
    }
}

В классе UserProvider можно реализовать любые бизнес-правила. Например, выбрать наименее загруженного пользователя из роли или отдела, выбрать следующего по очереди или хотя бы случайного пользователя из группы.

Назначение задач по полосе

Пользовательская задача, расположенная на полосе, может получать исполнителя и кандидатов от полосы. Чтобы задать их, выберите полосу:

Свойство

Описание

Id

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

Name

Имя элемента.

Assignee source

Назначение исполнителя по выражению, переменной процесса или через поставщика пользователей. См. Источники исполнителя.

Candidate groups

Группа пользователей, которым разрешено выполнять действия в пределах полосы.

Candidate users

Отдельные пользователи, которым разрешено выполнять действия в пределах полосы.

Documentation

Описание и дополнительные сведения об элементе.

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

В XML полосы представлены элементом laneSet и его элементами lane. Каждый элемент lane содержит свойства назначения и список размещенных на полосе элементов.

<process id="pool-and-lanes" name="Pool and lanes" isExecutable="true">
    <laneSet id="LaneSet_1lxq2l3">
      <lane id="Lane_1" name="User 1">
        <extensionElements>
          <jmix:assignmentDetails assigneeSource="expression" assigneeValue="user1" assignee="user1" candidateUsersSource="users" candidateGroupsSource="userGroups" />
        </extensionElements>
        <flowNodeRef>Activity_0n34ol9</flowNodeRef>
        <flowNodeRef>Activity_0758bjc</flowNodeRef>
        <flowNodeRef>Event_1mkoyrv</flowNodeRef>
      </lane>
      <lane id="Lane_2" name="User 2">
        ...
      </lane>
    </laneSet>

Назначение задачи из кода

Чтобы задать исполнителя задачи из кода, используйте метод setAssignee сервиса TaskService. Пример:

Task task = taskService.createTaskQuery()
                       .taskId("taskId")
                       .singleResult(); (1)

taskService.setAssignee(task.getId(), "jane"); (2)
1 получение объекта задачи через Query API
2 назначение исполнителя по имени пользователя

Задачи, назначенные определенному пользователю, можно получить через TaskService так:

List<Task> tasks = taskService.createTaskQuery()
    .taskAssignee("jane") (1)
    .list();
1 имя пользователя

Пользователи-кандидаты и группы-кандидаты задачи

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

Под «группами» здесь технически понимается список кодов User group.

Как забрать групповую задачу

Часто не важно, какой именно пользователь выполнит задачу. Например, менеджеру все равно, кто из двух бухгалтеров примет решение по его заказу.

В этом случае Jmix BPM позволяет назначить задачу списку кандидатов, и исполнителем может стать любой из них. Но сначала он должен забрать задачу. Забрать задачу — значит назначить ее на себя.

Задача с кандидатами появляется на экране My tasks в разделе Group tasks у каждого кандидата.

my tasks claim

После того как один из кандидатов забирает задачу, она переходит в список Assigned tasks этого пользователя и исчезает из списка Group tasks остальных кандидатов.

claiming form

Чтобы забрать задачу, пользователь должен открыть ее и выполнить одно из действий:

  • Claim and resume — пользователь становится исполнителем задачи, форма задачи открывается заново в обычном режиме, и с ней можно продолжить работу.

  • Claim and close — пользователь становится исполнителем задачи, форма задачи закрывается; позже ее можно найти в разделе Assigned tasks списка задач:

my tasks claimed task

Как забрать задачу из кода

Через API задачу можно забрать от имени указанного пользователя:

taskService.claim("taskId", "userId");

Задание кандидатов в моделере

Чтобы задать группы-кандидаты, нажмите кнопку Edit:

web modeler candidate groups

Откроется окно Candidate groups editor, где можно выбрать источник групп-кандидатов:

candidate groups sources
  • User groups — выбор групп пользователей из списка.

  • User groups provider — выбор специального Java-класса, который возвращает список групп пользователей.

  • Expression — получение списка групп пользователей из выражения, например из переменной процесса, определенной ранее в процессе.

Задание кандидатов по группам пользователей

Если в качестве источника выбран вариант User groups, можно выбрать любую из существующих групп пользователей:

selecting candidate grouos

Поставщик групп пользователей

Если при задании групп-кандидатов нужна сложная логика, лучше выбрать вариант User groups provider.

selecting user group provider

Он позволяет выбрать один из ранее созданных бинов Java с аннотацией @UserGroupListProvider. Этот бин должен реализовать один или несколько методов, которые возвращают List<String> с кодами групп пользователей.

У аннотации @UserGroupListProvider два атрибута:

  • value — имя, которое отображается в моделере.

  • description — необязательное пояснение назначения метода.

Пример:

@UserGroupListProvider(value="allGroups",
                       description = "Returns a list of all groups")
public class MyGroupListProvider {

    @Autowired
    private UserGroupService userGroupService;

    public List<String> getAllUserGroups() {
        List<UserGroup> allUserGroups = userGroupService.getAllUserGroups();
        if (!allUserGroups.isEmpty()) {
            return allUserGroups.stream().map(UserGroup::getCode).toList();
        } else {
            return Collections.emptyList();
        }
    }
}

Подробнее см. в разделе User groups.

Задание групп-кандидатов выражением

Самый общий способ задать параметры BPMN — выражение. Для групп-кандидатов он тоже доступен:

candidate groups expression

Варианты задания пользователей-кандидатов

Пользователи-кандидаты задаются на экране Web BPM Modeler почти так же, как группы-кандидаты. Доступны следующие источники:

candidate users options
  • User groups — выбор имен пользователей из списка.

  • User groups provider — выбор специального Java-класса, который возвращает список имен пользователей.

  • Expression — получение списка имен пользователей из выражения.

Поставщик списка пользователей

Как и в случае с User Groups Provider, список пользователей-кандидатов можно получить из кода, вызвав метод бина Spring с аннотацией @UserListProvider:

candidate user list provider

Пример:

@UserListProvider(value = "smpl_UserListProviderDemo",
                  description = "Get all users")
public class UserListProviderDemo {

    @Autowired
    private DataManager dataManager;
    @Autowired
    private SystemAuthenticator authenticator;

    public List<String> getAllUsers() {
        authenticator.begin();
        try {
            List<User> users = dataManager.load(User.class).all().list();
            return users.stream().map(User::getUsername).toList();
        } finally {
            authenticator.end();
        }
    }
}

Задание пользователей-кандидатов выражением

Также можно использовать самый общий способ задать параметр модели процесса — выражение:

candidate users expression

Например, так можно сослаться на имя пользователя из переменной с сущностью User:

${initiator.username}

CandidateUsers и candidateGroups можно задать в одной и той же пользовательской задаче.

Процессные формы пользовательской задачи

Для пользовательской задачи можно настроить процессную форму, чтобы помочь исполнителю ввести данные, необходимые для задачи. Затем собранные данные можно передать дальше в процесс.

Множественный экземпляр

Пользовательские задачи могут выполняться как множественный экземпляр. Подробнее об этом режиме см. в разделе Множественный экземпляр.

Настройка слушателей задач

Пользовательские задачи в Jmix BPM поддерживают слушатели задач, которые выполняют собственную логику в ответ на события задачи. Слушатели задач позволяют задать Java-классы или выражения, которые срабатывают при событиях пользовательской задачи.

task listeners field

Слушатели задач могут реагировать на следующие события пользовательской задачи:

  • create: срабатывает, когда пользовательская задача создана и заданы ее свойства, включая исполнителя.

  • assignment: срабатывает, когда меняется исполнитель пользовательской задачи. Если задача получает исполнителя при создании, assignment срабатывает перед create. Добавление пользователей-кандидатов или групп-кандидатов его не вызывает.

  • complete: срабатывает, когда пользовательская задача выполнена, перед delete.

  • delete: срабатывает перед удалением пользовательской задачи из данных времени выполнения — после complete или когда задача удаляется, например вместе с экземпляром процесса.

Чтобы настроить слушатель задач для пользовательской задачи, используйте элемент расширения flowable:taskListener в BPMN XML или метод addTaskListener в Java API.

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

XML-представление

<userTask id="approve-invoice" name="Approve invoice" jmix:assigneeSource="expression">
  <extensionElements>
    . . .
    <flowable:taskListener class="com.company.demo.listener.ApproverAssignment" (1)
                           event="assignment" /> (2)
  </extensionElements>
 . . .
</userTask>
1 Класс слушателя задач
2 Событие задачи

Уведомления

Начиная с Jmix 3.1

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

Другие дополнения расширяют эти возможности:

Чтобы выбирать тип уведомления в моделере, зарегистрируйте типы, как описано в разделе Типы уведомлений. Чтобы читать уведомления в приложении, получателям нужна роль, описанная в разделе Роли безопасности.

Каждое уведомление отправляется при событии задачи, выбранном в его свойстве Event: create, assignment, complete или delete. Это события слушателей задач, и Jmix BPM добавляет эти слушатели при развертывании процесса. Движок генерирует delete, когда задача выполнена, сразу после complete, а также когда прерывающее граничное событие отменяет задачу или удаляется экземпляр процесса.

Чтобы отправить уведомление в другой момент, прикрепите к задаче граничное событие и соедините его с задачей отправки уведомления. Например, непрерывающее граничное событие таймера может уведомить инициатора процесса, что задача не выполнена вовремя.

XML-представление

<userTask id="approve-order" name="Approve order">
  <extensionElements>
    <jmix:notification event="assignment" recipientType="assignee"
                       channels="in-app" contentType="plain">
      <jmix:subject>Task assigned: ${context.taskName}</jmix:subject>
      <jmix:body>Hello ${context.recipientUser.username}, please approve order ${order.number}.</jmix:body>
    </jmix:notification>
  </extensionElements>
</userTask>

В уведомлениях пользовательской задачи у объекта context, описанного в разделе Выражения в уведомлениях, также есть свойства taskId и taskName с id и именем задачи и свойство taskAssigneeUser с ее исполнителем.

Свойства уведомления

Раздел Notifications показывает список уведомлений. Для управления ими используйте кнопки Create, Edit и Remove. У уведомления есть следующие свойства:

Свойство

Описание

Subject

Тема уведомления. Обязательное свойство. Может содержать выражения.

Type

Необязательный тип уведомления. Задает значок уведомления в UI. Список показывает зарегистрированные типы; также можно ввести имя типа.

Event

Событие задачи, при котором отправляется уведомление. Обязательное свойство. См. Уведомления.

Recipient

Кто получает уведомление. Обязательное свойство. См. Получатели уведомлений.

Recipient expression

Выражение, которое возвращает получателей. Показывается, если Recipient имеет значение Expression.

Channels

In-app, Email или оба. Нужен хотя бы один канал. По умолчанию выбран In-app. Email доступен, если установлено дополнение Email Sending.

Use message template, Message template

Шаблон, по которому формируется текст. Доступно, если установлено дополнение Message Templates. См. Шаблоны сообщений в уведомлениях.

Content type

Plain text или HTML. Для HTML текст редактируется в редакторе форматированного текста. Если переключиться с HTML на обычный текст, моделер запрашивает подтверждение и очищает текст. Скрыто, если используется шаблон сообщения.

Body

Текст уведомления. Может содержать выражения. Скрыто, если используется шаблон сообщения.

В XML каждое уведомление — это элемент расширения jmix:notification. Его атрибуты: recipientType, recipientExpression, channels, type, contentType и templateCode; дочерние элементы: jmix:subject и jmix:body. Атрибут event хранит событие.

Получатели уведомлений

Recipient Значение в XML Описание

Task assignee

assignee

Если у задачи нет исполнителя, уведомление не отправляется.

Candidate users

candidateUsers

См. Пользователи-кандидаты и группы-кандидаты задачи.

Candidate groups

candidateGroups

Все пользователи групп-кандидатов задачи, в соответствии с типом группы.

Process initiator

initiator

Пользователь, сохраненный в переменной процесса initiator.

Expression

expression

Результат Recipient expression. Выражение может возвращать имя пользователя, пользователя или их коллекцию, например ${order.manager} или ${reviewers}.

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

Выражения в уведомлениях

Тема и текст — это выражения Flowable, например ${order.number} или ${context.recipientUser.username}. Значения вставляются с помощью toString(), поэтому для форматирования вызывайте методы, например ${order.date.getYear()}.

У объекта context есть следующие свойства:

Свойство Описание

recipientUser

Пользователь, который получает это уведомление.

processId

Id экземпляра процесса.

processDefinitionId, processDefinitionName

Id и имя определения процесса.

executionId

Id исполнения.

variables

Map переменных процесса, например ${context.variables.orderNumber}.

В теме и тексте context всегда означает контекст уведомления, даже если у процесса есть переменная с таким именем.

Шаблоны сообщений в уведомлениях

Если уведомление использует шаблон сообщения, шаблон формирует только текст. Тема по-прежнему берется из свойства Subject и использует выражения Flowable, а шаблон использует синтаксис FreeMarker.

Параметры шаблона заполняются из переменных процесса: алиас каждого параметра должен совпадать с именем переменной процесса. Например, если у процесса есть переменная order, добавьте параметр order и используйте ${order.number} в шаблоне. Объект context, описанный в разделе Выражения в уведомлениях, тоже доступен. Значения параметров по умолчанию не используются. Если шаблон ссылается на отсутствующую переменную, уведомление не отправляется, а ошибка записывается в лог.

Ошибки в уведомлениях

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

Уведомления в приложении сохраняются в отдельной транзакции, поэтому остаются, даже если транзакция процесса позже откатывается. Электронные письма отправляются асинхронно дополнением Email Sending. Получатель без адреса электронной почты не получает письмо, а в лог записывается предупреждение.

Документация

Дополнительную информацию для пользователя можно указать в параметре documentation (так он называется в BPMN) или description (так он называется в API). Его длина не может превышать 4000 символов.

Изначально поле documentation было предназначено для документирования модели процесса аналитиками. Но в пользовательской задаче его можно рассматривать как инструкцию для пользователя, объясняющую, что нужно сделать.

Это поле находится в самом конце панели свойств.

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