Исходник схемы
<?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_report_cycle" targetNamespace="urn:sharix:knowledge:handlers">
<bpmn:process id="aggregate_Process_aggregate" name="Агрегатор: снять snapshot, отправить, восстановить при полном неуспехе" isExecutable="false">
<bpmn:documentation>{"notes": ["BPMN isExecutable=false; typed operation aggregate_handler_reports из Blockly, Python сверён канонически.", "Буфер reports — память под lock, не durable outbox.", "Успешный send-call не равен доставке/прочтению; повтор после неизвестного результата может дублировать отчёт."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_report_handler.py", "repository": "sharix-open-handlers-examples", "sha256": "9607c7f5b6f91632027095f5b3ebf64961ff8fd9c4624e80b5a39c6742ce61d5"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_report_handler.json", "repository": "sharix-open-handlers-examples", "sha256": "b4c158eca9cc5e7fc671629a01d367edcd351ecdbce446544fd6a1d103f0323c"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "first_party_operations/open_report_handler.py", "repository": "sharix-open-handlers-examples", "sha256": "2caef84ded62efccbc6771b62e66e849b961ebcc62586083ea8f26f5cb918237"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "config.py", "repository": "sharix-open-handlers-examples", "sha256": "7b23db9ed283d3bbc3cf2cfbd5d41c629f6be507c3ca38c611572d08a75743a4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "first_party_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "7f4dc6607ad62f3150c58de6341b758ebe97f81bd936c9ec033b7d86fed44640"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/first_party_handler_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "fb5ee98561b029de9291e73c2a08205cc9fc2b7b239abffe4a4bb24f56093bdb"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "main.py", "repository": "sharix-open-handlers-backend", "sha256": "66b7df94fedbec931ed4cb2d4e1afd9cf0386e14ed0932e22b15eb301cd792d7"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "runtime_provider.py", "repository": "sharix-open-handlers-backend", "sha256": "c311d3b0721d18d8eccc9cd7fba155108bf285df3002507ee915ee73b797a2f4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/JabberBot.py", "repository": "sharix-open-handlers-backend", "sha256": "7fbd4d1f41bc867109b73dbb632efcfae920269a1aaf6da0e577cc70838820f1"}]}</bpmn:documentation>
<bpmn:laneSet id="aggregate_Lanes_aggregate">
<bpmn:lane id="aggregate_Lane_worker" name="После общего XMPP connection preflight">
<bpmn:flowNodeRef>aggregate_start</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_stop</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_exit</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_snapshot</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_empty</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_format</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_send</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_delivered</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_restore</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_wait</bpmn:flowNodeRef>
<bpmn:flowNodeRef>aggregate_repeat</bpmn:flowNodeRef>
</bpmn:lane>
</bpmn:laneSet>
<bpmn:startEvent id="aggregate_start" name="start_handler">
<bpmn:outgoing>aggregate_Flow_0</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:exclusiveGateway id="aggregate_stop" name="exit_event установлен?">
<bpmn:incoming>aggregate_Flow_0</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_1</bpmn:outgoing>
<bpmn:outgoing>aggregate_Flow_2</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:endEvent id="aggregate_exit" name="Завершить цикл, launcher закрывает XMPP">
<bpmn:incoming>aggregate_Flow_1</bpmn:incoming>
</bpmn:endEvent>
<bpmn:serviceTask id="aggregate_snapshot" name="Lock: скопировать reports и очистить буфер">
<bpmn:incoming>aggregate_Flow_2</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_3</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:exclusiveGateway id="aggregate_empty" name="Snapshot непустой?">
<bpmn:incoming>aggregate_Flow_3</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_4</bpmn:outgoing>
<bpmn:outgoing>aggregate_Flow_7</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:serviceTask id="aggregate_format" name="Собрать текст по JID и сообщениям">
<bpmn:incoming>aggregate_Flow_4</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_5</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sendTask id="aggregate_send" name="Попытаться отправить всем proceed_to, кроме себя">
<bpmn:incoming>aggregate_Flow_5</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_6</bpmn:outgoing>
</bpmn:sendTask>
<bpmn:exclusiveGateway id="aggregate_delivered" name="Хотя бы один send-call без исключения?">
<bpmn:incoming>aggregate_Flow_6</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_8</bpmn:outgoing>
<bpmn:outgoing>aggregate_Flow_10</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:serviceTask id="aggregate_restore" name="Нет: вернуть snapshot в начало текущих списков под lock">
<bpmn:incoming>aggregate_Flow_8</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_9</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:intermediateCatchEvent id="aggregate_wait" name="exit_event.wait(INTERVAL_TIME_REPORT)">
<bpmn:incoming>aggregate_Flow_7</bpmn:incoming>
<bpmn:incoming>aggregate_Flow_9</bpmn:incoming>
<bpmn:incoming>aggregate_Flow_10</bpmn:incoming>
<bpmn:outgoing>aggregate_Flow_11</bpmn:outgoing>
<bpmn:timerEventDefinition>
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">interval_time_report</bpmn:timeDuration>
</bpmn:timerEventDefinition>
</bpmn:intermediateCatchEvent>
<bpmn:endEvent id="aggregate_repeat" name="Проверить stop и повторить цикл">
<bpmn:incoming>aggregate_Flow_11</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="aggregate_Flow_0" sourceRef="aggregate_start" targetRef="aggregate_stop" name="" />
<bpmn:sequenceFlow id="aggregate_Flow_1" sourceRef="aggregate_stop" targetRef="aggregate_exit" name="Да" />
<bpmn:sequenceFlow id="aggregate_Flow_2" sourceRef="aggregate_stop" targetRef="aggregate_snapshot" name="Нет" />
<bpmn:sequenceFlow id="aggregate_Flow_3" sourceRef="aggregate_snapshot" targetRef="aggregate_empty" name="" />
<bpmn:sequenceFlow id="aggregate_Flow_4" sourceRef="aggregate_empty" targetRef="aggregate_format" name="Да" />
<bpmn:sequenceFlow id="aggregate_Flow_5" sourceRef="aggregate_format" targetRef="aggregate_send" name="" />
<bpmn:sequenceFlow id="aggregate_Flow_6" sourceRef="aggregate_send" targetRef="aggregate_delivered" name="" />
<bpmn:sequenceFlow id="aggregate_Flow_7" sourceRef="aggregate_empty" targetRef="aggregate_wait" name="Нет" />
<bpmn:sequenceFlow id="aggregate_Flow_8" sourceRef="aggregate_delivered" targetRef="aggregate_restore" name="Нет" />
<bpmn:sequenceFlow id="aggregate_Flow_9" sourceRef="aggregate_restore" targetRef="aggregate_wait" name="" />
<bpmn:sequenceFlow id="aggregate_Flow_10" sourceRef="aggregate_delivered" targetRef="aggregate_wait" name="Да" />
<bpmn:sequenceFlow id="aggregate_Flow_11" sourceRef="aggregate_wait" targetRef="aggregate_repeat" name="" />
</bpmn:process>
<bpmn:collaboration id="Collaboration_report_cycle">
<bpmn:participant id="aggregate_Pool_aggregate" name="Агрегатор: снять snapshot, отправить, восстановить при полном неуспехе" processRef="aggregate_Process_aggregate" />
<bpmn:participant id="recipient_Participant" name="Технический получатель отчётов: фиксированный в operation UID, не staff-группа по Ticket" />
<bpmn:messageFlow id="Message_report_cycle_0" sourceRef="aggregate_send" targetRef="recipient_Participant" name="XMPP chat; нет receipt, редакторской реакции или durable квитанции" />
</bpmn:collaboration>
<bpmndi:BPMNDiagram id="Diagram_report_cycle">
<bpmndi:BPMNPlane id="Plane_report_cycle" bpmnElement="Collaboration_report_cycle">
<bpmndi:BPMNShape id="aggregate_DI_Pool_aggregate" bpmnElement="aggregate_Pool_aggregate" isHorizontal="true">
<dc:Bounds x="0.0" y="0.0" width="2150" height="680" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_Lane_worker" bpmnElement="aggregate_Lane_worker" isHorizontal="true">
<dc:Bounds x="30.0" y="0.0" width="2120" height="680" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_start" bpmnElement="aggregate_start">
<dc:Bounds x="132.0" y="82.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_stop" bpmnElement="aggregate_stop">
<dc:Bounds x="415.0" y="75.0" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_exit" bpmnElement="aggregate_exit">
<dc:Bounds x="422.0" y="322.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_snapshot" bpmnElement="aggregate_snapshot">
<dc:Bounds x="675.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_empty" bpmnElement="aggregate_empty">
<dc:Bounds x="1035.0" y="75.0" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_format" bpmnElement="aggregate_format">
<dc:Bounds x="1295.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_send" bpmnElement="aggregate_send">
<dc:Bounds x="1605.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_delivered" bpmnElement="aggregate_delivered">
<dc:Bounds x="1965.0" y="75.0" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_restore" bpmnElement="aggregate_restore">
<dc:Bounds x="1915.0" y="305.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_wait" bpmnElement="aggregate_wait">
<dc:Bounds x="1352.0" y="562.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="aggregate_DI_repeat" bpmnElement="aggregate_repeat">
<dc:Bounds x="1662.0" y="562.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_0" bpmnElement="aggregate_Flow_0">
<di:waypoint x="168.0" y="100.0" />
<di:waypoint x="415.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_1" bpmnElement="aggregate_Flow_1">
<di:waypoint x="440.0" y="125.0" />
<di:waypoint x="440.0" y="322.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_2" bpmnElement="aggregate_Flow_2">
<di:waypoint x="465.0" y="100.0" />
<di:waypoint x="675.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_3" bpmnElement="aggregate_Flow_3">
<di:waypoint x="825.0" y="100.0" />
<di:waypoint x="1035.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_4" bpmnElement="aggregate_Flow_4">
<di:waypoint x="1085.0" y="100.0" />
<di:waypoint x="1295.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_5" bpmnElement="aggregate_Flow_5">
<di:waypoint x="1445.0" y="100.0" />
<di:waypoint x="1605.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_6" bpmnElement="aggregate_Flow_6">
<di:waypoint x="1755.0" y="100.0" />
<di:waypoint x="1965.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_7" bpmnElement="aggregate_Flow_7">
<di:waypoint x="1085.0" y="100.0" />
<di:waypoint x="1180.0" y="100.0" />
<di:waypoint x="1230.0" y="100.0" />
<di:waypoint x="1230.0" y="510.0" />
<di:waypoint x="1370.0" y="510.0" />
<di:waypoint x="1370.0" y="562.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_8" bpmnElement="aggregate_Flow_8">
<di:waypoint x="1990.0" y="125.0" />
<di:waypoint x="1990.0" y="305.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_9" bpmnElement="aggregate_Flow_9">
<di:waypoint x="2065.0" y="340.0" />
<di:waypoint x="2110.0" y="340.0" />
<di:waypoint x="2170.0" y="340.0" />
<di:waypoint x="2170.0" y="510.0" />
<di:waypoint x="1370.0" y="510.0" />
<di:waypoint x="1370.0" y="562.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_10" bpmnElement="aggregate_Flow_10">
<di:waypoint x="2015.0" y="100.0" />
<di:waypoint x="2110.0" y="100.0" />
<di:waypoint x="2170.0" y="100.0" />
<di:waypoint x="2170.0" y="510.0" />
<di:waypoint x="1370.0" y="510.0" />
<di:waypoint x="1370.0" y="562.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="aggregate_DI_Flow_11" bpmnElement="aggregate_Flow_11">
<di:waypoint x="1388.0" y="580.0" />
<di:waypoint x="1662.0" y="580.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="DI_recipient_Participant" bpmnElement="recipient_Participant" isHorizontal="true">
<dc:Bounds x="0" y="900" width="2300" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="DI_Message_report_cycle_0" bpmnElement="Message_report_cycle_0">
<di:waypoint x="1680" y="135" />
<di:waypoint x="1680" y="800" />
<di:waypoint x="1200" y="800" />
<di:waypoint x="1200" y="900" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1300" y="760" width="260" height="42" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>