Инструменты пользователя

Инструменты сайта


sharixopen:knowledge:scenarios:st_request_waiting

Это старая версия документа!


Новая ST_REQUEST: ожидание, очередь и переход в ASSIGNED

Сценарий описывает open_st_request_new в ShariX Open. Его работа — обработать Ticket типа ST_REQUEST в статусе NEW: отложить локальную проверку либо запросить переход в ASSIGNED. Это анализ текущего кода; конфигурация и выбранная версия конкретного сервера проверяются отдельно.

Какие источники определяют поведение

  • Алгоритм: handlers_examples/generated_handler_blocks/open_st_request_new.json.
  • Исполняемый Python: handlers_examples/handlers/open_st_request_new.py.
  • Копия результата генерации: handlers_examples/generated_handlers/open_st_request_new.py.
  • Генерация: handlers_backend/ticket_blockly_codegen.py и ticket_codegen_contract.json.
  • Очередь, отсрочка и сетевые операции: handlers_backend/core/blockly_runtime.py.
  • Проверка обработчика на стороне API: tickets/api/views/handler_workflow.py и capabilities каталога.

31.10.2026 Python заново получен из workspace: обе поставляемые копии совпали с результатом побайтово. Проверены хеши 11 исходников генераторов, перечисленных в контракте. Сам handler при этой проверке не запускался; серверные настройки и XMPP не проверялись.

Ветви одного прохода

Условие Что делает код Что это означает
Ticket имеет статус NEW, STREQ_AUTOACCEPT выключен Записывает support_assignment и откладывает проверку на ST_REQUEST_NEW_RECHECK_SECONDS. Ожидается внешнее назначение/изменение; worker не остаётся спать на этом Ticket.
Ticket имеет статус NEW, STREQ_AUTOACCEPT включён Запрашивает ASSIGNED; после успеха отправляет Ticket open_st_request_assigned и удаляет из своей очереди с delete_room=False. Передаётся обработка следующей стадии. Конкретного сотрудника эта ветвь не выбирает и assigned_to не заполняет.
На проверку пришёл Ticket уже с другим статусом Убирает локальное состояние и запрашивает удаление комнаты уведомлений. Данный handler прекращает обработку. Сам Ticket из backend не удаляется.
Scoped API перехода вернул 404 change_status убирает локальный снимок и возвращает False. Ticket больше не доступен в рабочей области этого handler; повторный переход в этом проходе не выполняется.
Переход или отправка завершились другой ошибкой Ошибка передаётся общему runtime для его обработки отказа и повторов. Передачу нельзя объявлять успешно завершённой по одному намерению отправки.

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

Полный алгоритм и очередь (BPMN)

Схема описательная: isExecutable=false. Дорожки показывают worker и планировщик, а deferred_until обозначает вычисленный локальный срок, не отдельную настройку установки. Просмотр схемы не запускает процесс и не создаёт таймер.

Схема BPMN

Загрузка схемы…

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_st_new_logic" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="new_Process_new" name="open_st_request_new: Python и локальная очередь" isExecutable="false">
    <bpmn:documentation>{"notes": ["Описание Git built-in; реальные локальные версии сверяются отдельно.", "Worker не занят во время defer. Символ deferred_until означает текущий локальный срок.", "Граница ошибки включает ошибку API/отправки, но не отменяет уже зафиксированный переход."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_st_request_assigned.json", "repository": "sharix-open-handlers-examples", "sha256": "d49e943a8806c3130acf09f1e93cf6b4e4a7d6f7428a5d18844a8f64ff619fe6"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_st_request_assigned.py", "repository": "sharix-open-handlers-examples", "sha256": "2be4d63c70b8469e541346aa3185bb29d04af1a87fb64fb1df118bde3ebe3c42"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_st_request_new.json", "repository": "sharix-open-handlers-examples", "sha256": "6b76b94236e6257f1f13dff9f41bb48c47352d5c512c9add0c5e53153c2dd6ff"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_st_request_new.py", "repository": "sharix-open-handlers-examples", "sha256": "f3cc74eccbc60431fff10e4989a4e499af85c7190b2e30cba8b097639cf1a23f"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/blockly_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "3e222150cbff315077c6c9b160d46e59856cedf6d6591d213e958c63cb2f2428"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "signals.py", "repository": "sharix-open-tickets", "sha256": "39aad8690a2e7d35cebfb052127a8130a951cbb4eea316c4f767a0a59fc5fa7e"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "services/handler_wakeup.py", "repository": "sharix-open-tickets", "sha256": "c9fdc62a18301fd7c075395c697d5b1c738c77713aa71fcbb5ab097e173d98de"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "utils.py", "repository": "sharix-open-tickets", "sha256": "a5680205c6522e1d9a74d9d267fe9ee96faf6f06436b00877fc0a93d80234bf5"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "views/ticket_detail.py", "repository": "sharix-open-tickets", "sha256": "05d344b0fba14cf895400694d4a18f486c800fef08dd1acb43ea46909b9e7e59"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/views/ticket.py", "repository": "sharix-open-tickets", "sha256": "b25a66fc52790f11ba7aca48527a4a5b6640a05ffa377ab58f562955f2695499"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/permissions.py", "repository": "sharix-open-tickets", "sha256": "a0e12d188313ae1e6a9b1502ec48c2dd7f76fffa78ecf50b5b1b33b040b290a1"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "urls.py", "repository": "sharix-open-tickets", "sha256": "c41101b32eb1132d63bf62d5bd96d344a79fe34946dc1635dc090921beb6e3c9"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "lib/tickets.py", "repository": "sharix-open-tickets", "sha256": "0d260c17947f9a186d07af2749159780e3c7354a95b4bafe9d67493663c96883"}]}</bpmn:documentation>
    <bpmn:laneSet id="new_Lanes_new">
      <bpmn:lane id="new_Lane_worker" name="Выполнение Python (один проход)">
        <bpmn:flowNodeRef>new_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_status</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_auto</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_reason</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_defer</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_cleanup</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_stale_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_transition</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_confirmed</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_false_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_handoff</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_remove</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_success</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_api_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_send_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_retry</bpmn:flowNodeRef>
      </bpmn:lane>
      <bpmn:lane id="new_Lane_scheduler" name="Планировщик: между проходами, без занятого worker">
        <bpmn:flowNodeRef>new_waiting</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_due</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_revision</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>new_ready</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="new_start" name="Ticket готов к проходу">
      <bpmn:outgoing>new_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:exclusiveGateway id="new_status" name="Снимок в NEW?">
      <bpmn:incoming>new_Flow_0</bpmn:incoming>
      <bpmn:incoming>new_Flow_20</bpmn:incoming>
      <bpmn:outgoing>new_Flow_1</bpmn:outgoing>
      <bpmn:outgoing>new_Flow_2</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:exclusiveGateway id="new_auto" name="STREQ_AUTOACCEPT?">
      <bpmn:incoming>new_Flow_1</bpmn:incoming>
      <bpmn:outgoing>new_Flow_4</bpmn:outgoing>
      <bpmn:outgoing>new_Flow_7</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="new_reason" name="Записать support_assignment">
      <bpmn:documentation>Локальная причина ожидания, не комментарий Ticket.</bpmn:documentation>
      <bpmn:incoming>new_Flow_4</bpmn:incoming>
      <bpmn:outgoing>new_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="new_defer" name="Назначить повтор проверки">
      <bpmn:documentation>ST_REQUEST_NEW_RECHECK_SECONDS; вернуть Ticket, освободив worker.</bpmn:documentation>
      <bpmn:incoming>new_Flow_5</bpmn:incoming>
      <bpmn:outgoing>new_Flow_6</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="new_cleanup" name="Убрать локальный Ticket и комнату">
      <bpmn:incoming>new_Flow_2</bpmn:incoming>
      <bpmn:outgoing>new_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="new_stale_end" name="Этот handler больше не владеет Ticket">
      <bpmn:incoming>new_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="new_transition" name="Scoped API: ASSIGNED">
      <bpmn:documentation>ticket.transition; 404 означает устаревший scope, другие ошибки — исключение.</bpmn:documentation>
      <bpmn:incoming>new_Flow_7</bpmn:incoming>
      <bpmn:outgoing>new_Flow_8</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="new_confirmed" name="Переход подтверждён?">
      <bpmn:incoming>new_Flow_8</bpmn:incoming>
      <bpmn:outgoing>new_Flow_9</bpmn:outgoing>
      <bpmn:outgoing>new_Flow_10</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:endEvent id="new_false_end" name="404: очистка уже запрошена">
      <bpmn:incoming>new_Flow_9</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sendTask id="new_handoff" name="Передать Ticket в ASSIGNED handler">
      <bpmn:documentation>open_st_request_assigned; попытка отправки XMPP, не завершение следующей стадии.</bpmn:documentation>
      <bpmn:incoming>new_Flow_10</bpmn:incoming>
      <bpmn:outgoing>new_Flow_11</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:serviceTask id="new_remove" name="Убрать Ticket; комнату сохранить">
      <bpmn:incoming>new_Flow_11</bpmn:incoming>
      <bpmn:outgoing>new_Flow_12</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="new_success" name="Передача текущего handler завершена">
      <bpmn:incoming>new_Flow_12</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:boundaryEvent id="new_api_error" name="Ошибка API" attachedToRef="new_transition" cancelActivity="true">
      <bpmn:outgoing>new_Flow_13</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="new_send_error" name="Ошибка отправки" attachedToRef="new_handoff" cancelActivity="true">
      <bpmn:outgoing>new_Flow_14</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:serviceTask id="new_retry" name="Ошибка: processing_error и defer">
      <bpmn:documentation>Общий runtime: DEFERRED_TICKET_RECHECK_SECONDS; уже committed status не откатывается.</bpmn:documentation>
      <bpmn:incoming>new_Flow_13</bpmn:incoming>
      <bpmn:incoming>new_Flow_14</bpmn:incoming>
      <bpmn:outgoing>new_Flow_15</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:eventBasedGateway id="new_waiting" name="Что наступило раньше?">
      <bpmn:incoming>new_Flow_6</bpmn:incoming>
      <bpmn:incoming>new_Flow_15</bpmn:incoming>
      <bpmn:outgoing>new_Flow_16</bpmn:outgoing>
      <bpmn:outgoing>new_Flow_17</bpmn:outgoing>
    </bpmn:eventBasedGateway>
    <bpmn:intermediateCatchEvent id="new_due" name="Текущий срок defer наступил">
      <bpmn:incoming>new_Flow_16</bpmn:incoming>
      <bpmn:outgoing>new_Flow_18</bpmn:outgoing>
      <bpmn:timerEventDefinition>
        <bpmn:timeDate xsi:type="bpmn:tFormalExpression">deferred_until</bpmn:timeDate>
      </bpmn:timerEventDefinition>
    </bpmn:intermediateCatchEvent>
    <bpmn:intermediateCatchEvent id="new_revision" name="Подтверждена новая ревизия Ticket">
      <bpmn:documentation>Уже получен новый authoritative snapshot. Дубликат сам по себе не снимает defer.</bpmn:documentation>
      <bpmn:incoming>new_Flow_17</bpmn:incoming>
      <bpmn:outgoing>new_Flow_19</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:intermediateCatchEvent>
    <bpmn:serviceTask id="new_ready" name="Снять defer, поставить в ready FIFO">
      <bpmn:documentation>Запуск возможен при готовом XMPP и свободном worker.</bpmn:documentation>
      <bpmn:incoming>new_Flow_18</bpmn:incoming>
      <bpmn:incoming>new_Flow_19</bpmn:incoming>
      <bpmn:outgoing>new_Flow_20</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="new_Flow_0" sourceRef="new_start" targetRef="new_status" name="" />
    <bpmn:sequenceFlow id="new_Flow_1" sourceRef="new_status" targetRef="new_auto" name="Да" />
    <bpmn:sequenceFlow id="new_Flow_2" sourceRef="new_status" targetRef="new_cleanup" name="Нет" />
    <bpmn:sequenceFlow id="new_Flow_3" sourceRef="new_cleanup" targetRef="new_stale_end" name="" />
    <bpmn:sequenceFlow id="new_Flow_4" sourceRef="new_auto" targetRef="new_reason" name="Нет" />
    <bpmn:sequenceFlow id="new_Flow_5" sourceRef="new_reason" targetRef="new_defer" name="" />
    <bpmn:sequenceFlow id="new_Flow_6" sourceRef="new_defer" targetRef="new_waiting" name="" />
    <bpmn:sequenceFlow id="new_Flow_7" sourceRef="new_auto" targetRef="new_transition" name="Да" />
    <bpmn:sequenceFlow id="new_Flow_8" sourceRef="new_transition" targetRef="new_confirmed" name="" />
    <bpmn:sequenceFlow id="new_Flow_9" sourceRef="new_confirmed" targetRef="new_false_end" name="Нет (404)" />
    <bpmn:sequenceFlow id="new_Flow_10" sourceRef="new_confirmed" targetRef="new_handoff" name="Да" />
    <bpmn:sequenceFlow id="new_Flow_11" sourceRef="new_handoff" targetRef="new_remove" name="" />
    <bpmn:sequenceFlow id="new_Flow_12" sourceRef="new_remove" targetRef="new_success" name="" />
    <bpmn:sequenceFlow id="new_Flow_13" sourceRef="new_api_error" targetRef="new_retry" name="" />
    <bpmn:sequenceFlow id="new_Flow_14" sourceRef="new_send_error" targetRef="new_retry" name="" />
    <bpmn:sequenceFlow id="new_Flow_15" sourceRef="new_retry" targetRef="new_waiting" name="" />
    <bpmn:sequenceFlow id="new_Flow_16" sourceRef="new_waiting" targetRef="new_due" name="" />
    <bpmn:sequenceFlow id="new_Flow_17" sourceRef="new_waiting" targetRef="new_revision" name="" />
    <bpmn:sequenceFlow id="new_Flow_18" sourceRef="new_due" targetRef="new_ready" name="" />
    <bpmn:sequenceFlow id="new_Flow_19" sourceRef="new_revision" targetRef="new_ready" name="" />
    <bpmn:sequenceFlow id="new_Flow_20" sourceRef="new_ready" targetRef="new_status" name="Новый проход" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_st_new_logic">
    <bpmn:participant id="new_Pool_new" name="open_st_request_new: Python и локальная очередь" processRef="new_Process_new" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_st_new_logic">
    <bpmndi:BPMNPlane id="Plane_st_new_logic" bpmnElement="Collaboration_st_new_logic">
      <bpmndi:BPMNShape id="new_DI_Pool_new" bpmnElement="new_Pool_new" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="1880" height="880" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_Lane_worker" bpmnElement="new_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="1850" height="550.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_Lane_scheduler" bpmnElement="new_Lane_scheduler" isHorizontal="true">
        <dc:Bounds x="30.0" y="550.0" width="1850" height="330.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_start" bpmnElement="new_start">
        <dc:Bounds x="142.0" y="102.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_status" bpmnElement="new_status">
        <dc:Bounds x="325.0" y="95.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_auto" bpmnElement="new_auto">
        <dc:Bounds x="535.0" y="95.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_reason" bpmnElement="new_reason">
        <dc:Bounds x="725.0" y="85.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_defer" bpmnElement="new_defer">
        <dc:Bounds x="965.0" y="85.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_cleanup" bpmnElement="new_cleanup">
        <dc:Bounds x="275.0" y="265.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_stale_end" bpmnElement="new_stale_end">
        <dc:Bounds x="542.0" y="282.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_transition" bpmnElement="new_transition">
        <dc:Bounds x="725.0" y="265.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_confirmed" bpmnElement="new_confirmed">
        <dc:Bounds x="1015.0" y="275.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_false_end" bpmnElement="new_false_end">
        <dc:Bounds x="1022.0" y="442.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_handoff" bpmnElement="new_handoff">
        <dc:Bounds x="1205.0" y="265.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_remove" bpmnElement="new_remove">
        <dc:Bounds x="1445.0" y="265.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_success" bpmnElement="new_success">
        <dc:Bounds x="1702.0" y="282.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_api_error" bpmnElement="new_api_error">
        <dc:Bounds x="832.0" y="317.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_send_error" bpmnElement="new_send_error">
        <dc:Bounds x="1312.0" y="317.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_retry" bpmnElement="new_retry">
        <dc:Bounds x="1205.0" y="445.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_waiting" bpmnElement="new_waiting">
        <dc:Bounds x="1015.0" y="635.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_due" bpmnElement="new_due">
        <dc:Bounds x="1262.0" y="602.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_revision" bpmnElement="new_revision">
        <dc:Bounds x="1262.0" y="762.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="new_DI_ready" bpmnElement="new_ready">
        <dc:Bounds x="1445.0" y="625.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="new_DI_Flow_0" bpmnElement="new_Flow_0">
        <di:waypoint x="178.0" y="120.0" />
        <di:waypoint x="325.0" y="120.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_1" bpmnElement="new_Flow_1">
        <di:waypoint x="375.0" y="120.0" />
        <di:waypoint x="535.0" y="120.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_2" bpmnElement="new_Flow_2">
        <di:waypoint x="350.0" y="145.0" />
        <di:waypoint x="350.0" y="265.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_3" bpmnElement="new_Flow_3">
        <di:waypoint x="425.0" y="300.0" />
        <di:waypoint x="542.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_4" bpmnElement="new_Flow_4">
        <di:waypoint x="585.0" y="120.0" />
        <di:waypoint x="725.0" y="120.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_5" bpmnElement="new_Flow_5">
        <di:waypoint x="875.0" y="120.0" />
        <di:waypoint x="965.0" y="120.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_6" bpmnElement="new_Flow_6">
        <di:waypoint x="1115.0" y="120.0" />
        <di:waypoint x="1780.0" y="120.0" />
        <di:waypoint x="1780.0" y="565.0" />
        <di:waypoint x="1040.0" y="565.0" />
        <di:waypoint x="1040.0" y="635.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_7" bpmnElement="new_Flow_7">
        <di:waypoint x="585.0" y="120.0" />
        <di:waypoint x="655.0" y="120.0" />
        <di:waypoint x="655.0" y="300.0" />
        <di:waypoint x="725.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_8" bpmnElement="new_Flow_8">
        <di:waypoint x="875.0" y="300.0" />
        <di:waypoint x="1015.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_9" bpmnElement="new_Flow_9">
        <di:waypoint x="1040.0" y="325.0" />
        <di:waypoint x="1040.0" y="442.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_10" bpmnElement="new_Flow_10">
        <di:waypoint x="1065.0" y="300.0" />
        <di:waypoint x="1205.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_11" bpmnElement="new_Flow_11">
        <di:waypoint x="1355.0" y="300.0" />
        <di:waypoint x="1445.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_12" bpmnElement="new_Flow_12">
        <di:waypoint x="1595.0" y="300.0" />
        <di:waypoint x="1702.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_13" bpmnElement="new_Flow_13">
        <di:waypoint x="868.0" y="335.0" />
        <di:waypoint x="900.0" y="335.0" />
        <di:waypoint x="900.0" y="400.0" />
        <di:waypoint x="1280.0" y="400.0" />
        <di:waypoint x="1280.0" y="445.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_14" bpmnElement="new_Flow_14">
        <di:waypoint x="1348.0" y="335.0" />
        <di:waypoint x="1400.0" y="335.0" />
        <di:waypoint x="1400.0" y="400.0" />
        <di:waypoint x="1280.0" y="400.0" />
        <di:waypoint x="1280.0" y="445.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_15" bpmnElement="new_Flow_15">
        <di:waypoint x="1355.0" y="480.0" />
        <di:waypoint x="1400.0" y="520.0" />
        <di:waypoint x="1040.0" y="520.0" />
        <di:waypoint x="1040.0" y="635.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_16" bpmnElement="new_Flow_16">
        <di:waypoint x="1065.0" y="660.0" />
        <di:waypoint x="1163.5" y="660.0" />
        <di:waypoint x="1163.5" y="620.0" />
        <di:waypoint x="1262.0" y="620.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_17" bpmnElement="new_Flow_17">
        <di:waypoint x="1065.0" y="660.0" />
        <di:waypoint x="1163.5" y="660.0" />
        <di:waypoint x="1163.5" y="780.0" />
        <di:waypoint x="1262.0" y="780.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_18" bpmnElement="new_Flow_18">
        <di:waypoint x="1298.0" y="620.0" />
        <di:waypoint x="1371.5" y="620.0" />
        <di:waypoint x="1371.5" y="660.0" />
        <di:waypoint x="1445.0" y="660.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_19" bpmnElement="new_Flow_19">
        <di:waypoint x="1298.0" y="780.0" />
        <di:waypoint x="1371.5" y="780.0" />
        <di:waypoint x="1371.5" y="660.0" />
        <di:waypoint x="1445.0" y="660.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="new_DI_Flow_20" bpmnElement="new_Flow_20">
        <di:waypoint x="1595.0" y="660.0" />
        <di:waypoint x="1840.0" y="660.0" />
        <di:waypoint x="1840.0" y="45.0" />
        <di:waypoint x="350.0" y="45.0" />
        <di:waypoint x="350.0" y="95.0" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1525.0" y="15.0" width="180" height="26" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Как устроено ручное ожидание

  1. Handler сверяет текущий статус Ticket с NEW.
  2. При выключенном STREQ_AUTOACCEPT сохраняет в памяти причину support_assignment.
  3. defer_ticket_for_setting читает ST_REQUEST_NEW_RECHECK_SECONDS через конфигурацию handlers; требуется положительное целое значение, минимум одна секунда. Значение конкретного сервера по этой статье не определяется.
  4. Ticket получает локальный срок defer, текущий проход заканчивается, а очередь может выполнять другие готовые элементы.
  5. После срока планировщик возвращает элемент в готовую очередь. Фактическое начало зависит от доступного worker и готовности XMPP; это не обещание запуска ровно в момент срока.
  6. Распознанное внешнее событие может снять отсрочку раньше. request_ticket_ready очищает локальный defer и будит планировщик; обновлённое состояние заново участвует в решении.

Причина ожидания и срок находятся в памяти процесса. После restart они не восстанавливаются как долговечное бизнес-обязательство: очередь получает актуальные Ticket из backend и оценивает их заново. Такой defer не заменяет журнал решений сотрудника или сохранённый SLA-таймер.

Передача NEW → ASSIGNED

  1. Обработчик вызывает scoped transition API с capability ticket.transition.
  2. Backend ограничивает Ticket типом и рабочим статусом handler, проверяет допустимость перехода и сохраняет Event в транзакции.
  3. После commit ticket.changed адресуется новому handler, а ticket.moved — прежнему.
  4. Сама Python-ветвь NEW после успешного перехода также отправляет Ticket в open_st_request_assigned и убирает его из своей очереди, сохраняя комнату при этой передаче.

Смена Ticket.status, попытка XMPP-отправки и фактическая работа следующего handler — отдельные наблюдаемые результаты. Если отправка после смены статуса не удалась, уже сохранённый переход не становится автоматически отменённым. Подробности внешних участников и восстановления — сценарий ASSIGNED.

Сверка очереди и ошибки

Runtime периодически сопоставляет локальный состав с backend. В результате он может:

  • обновить снимок Ticket;
  • сделать обновлённый элемент готовым;
  • исключить Ticket, который больше не входит в рабочую область;
  • восстановить состав после пропущенного события или перезапуска.

Поэтому изменение статуса не обязано доходить до ELSE на схеме: элемент может быть исключён раньше по событию или успешной сверке. Ошибка запроса сверки не доказывает исчезновения Ticket: runtime сохраняет локальный снимок и пишет диагностику. Ошибки загрузки, исчерпание попыток и остановка относятся к общему runtime; эта диаграмма не разворачивает все его аварийные ветви.

Что записать при разборе зависания

  • ID Ticket, его тип и сохранённый статус в backend.
  • Фактически выбранную версию handler, workspace и Python.
  • Действующие значения STREQ_AUTOACCEPT и ST_REQUEST_NEW_RECHECK_SECONDS — без секретов конфигурации.
  • Был ли Ticket принят в очередь и есть ли локальные причина ожидания/срок defer.
  • Какое событие или успешная сверка поступили после этого.
  • Готовность XMPP и наличие свободного worker.
  • Последний restart процесса: после него старые локальные признаки не считаются сохранёнными.
  • Результат transition API и отдельно результат отправки следующему handler, если выполнялась автоматическая ветвь.

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

Связанные материалы

Исходники, сверенные 31.10.2026

Проверены опубликованные исходники указанных commits. Это анализ кода, а не подтверждение версии, конфигурации или выполнения сценария на сервере.

sharixopen/knowledge/scenarios/st_request_waiting.1793443169.txt.gz · Последнее изменение: — sx_knowledge_api_open

© 2022 ShariX