run_global_ticker()

Домен: SIMULATION | Контур: Управление системным временем

WarningОграничение публичной документации

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

  • Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).

1. Бизнес-спецификация метода

  • Идентификатор метода: BPDS-SIM-M01
  • Системное имя: run_global_ticker()
  • Микросервис: simulation-core-engine
  • Домен: SIMULATION
  • Класс / Компонент: simulation.engine.ticker.SimulationTicker

1.1. Описание логики работы

Метод является главным мотором симулятора. Он работает в непрерывном цикле в памяти сервера. Его задача — раз в определенное время переключать виртуальные часы симуляции на 1 час (1 такт) вперед.

Поскольку поведение жителей зависит от времени (ночью люди спят, в обед едят, вечером после работы идут в магазин), этот метод берет порядковый номер часа симуляции и переводит его в понятный календарь: вычисляет текущий час суток (от 0 до 23) и день недели.

1.2. Пошаговое выполнение

  1. Виртуальная пауза: Метод выдерживает паузу (например, 1 секунду), чтобы симуляция не шла слишком быстро.
  2. Переключение часов: Порядковый номер текущего часа симуляции увеличивается на +1.
  3. Расчет часа в Алматы: Вычисляется час суток методом деления текущего такта по модулю 24.
  4. Расчет дня недели: Вычисляется текущий день недели (принимая старт симуляции за Понедельник).
  5. Сохранение: Номер часа записывается в системную таблицу базы данных, чтобы при случайном сбое симулятор мог продолжить работу с того же момента.
  6. Передача дальше: Сформированные данные о времени передаются Диспетчеру (Метод 2) для проверки активности пользователей.

2. Диаграмма последовательности метода (Вход и Выход флоу)

Диаграмма наглядно показывает, как метод инициализируется, выполняет внутренние расчеты, обновляет базу данных и передает управление Метод 2.

sequenceDiagram
    autonumber
    participant App as Контекст Приложения
    participant Ticker as SimulationTicker
    participant DB as База Данных Симулятора
    participant Disp as Диспетчер Активации

    %% ИНИЦИАЛИЗАЦИЯ
    App->>Ticker: Инициализация при старте (Вызов run global ticker)
    activate Ticker
    
    Note over Ticker: Вход метода: Отсутствует (Автономный запуск)<br/>Метод вычитывает прошлый час из базы данных
    
    loop Бесконечный цикл симуляции
        Ticker->>Ticker: Пауза времени (sleep)
        Ticker->>Ticker: Инкремент часа: t = t + 1
        
        %% ВНУТРЕННИЕ РАСЧЕТЫ
        Ticker->>Ticker: Расчет часа суток: t % 24
        Ticker->>Ticker: Расчет дня недели: (t / 24) % 7
        
        %% ОБНОВЛЕНИЕ СОСТОЯНИЯ
        Ticker->>DB: UPDATE system ledger SET long value = t
        DB-->>Ticker: База данных: Успешно обновлено
        
        Note over Ticker: Выход метода: Сформированный контекст времени Алматы
        
        %% ПЕРЕДАЧА УПРАВЛЕНИЯ СЛЕДУЮЩЕМУ МЕТОДУ
        Ticker->>Disp: Вызов processActivation(AlmatyTimeContext)
        activate Disp
        Note over Disp: Управление передано в Метод 2 (calculate activation probability)
        deactivate Disp
    end
    deactivate Ticker


3. Схемы данных и SQL-взаимодействие

Этот метод взаимодействует с внутренней базой данных симулятора для сохранения и восстановления текущего часа.

3.1. Структура системной таблицы

CREATE SCHEMA IF NOT EXISTS simulation;

-- Таблица для сохранения текущего состояния виртуальных часов
CREATE TABLE simulation.system_ledger (
    system_key VARCHAR(64) PRIMARY KEY,
    long_value BIGINT NOT NULL,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

3.2. Первоначальный запуск (Вставка стартовых данных)

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

INSERT INTO simulation.system_ledger (system_key, long_value) 
VALUES ('CURRENT_SIMULATION_TICK', 0)
ON CONFLICT (system_key) DO NOTHING;

3.3. Чтение при восстановлении (Запрос на получение данных)

Если контейнер с симулятором перезапустился, он считывает, на каком часу остановился:

SELECT long_value FROM simulation.system_ledger WHERE system_key = 'CURRENT_SIMULATION_TICK';

3.4. Сохранение текущего часа (Запрос на обновление данных)

На каждом шаге метод обновляет значение в базе данных:

UPDATE simulation.system_ledger 
SET long_value = 105, updated_at = CURRENT_TIMESTAMP 
WHERE system_key = 'CURRENT_SIMULATION_TICK';

4. Спецификация обмена данными (Вход / Выход)

Так как этот метод работает автономно внутри памяти и запускается сам, у него нет входящих сетевых запросов (Request). Он генерирует структуру данных времени и передает её внутри программы следующему методу.

4.1. Структура выходных данных времени (Входные данные для Метода 2)

{
  "global_tick": 105,
  "hour_of_day": 19,
  "day_of_week": "FRIDAY"
}

5. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: BACKEND

Заголовок: Реализация часов симулятора run_global_ticker и расчета времени Алматы

5.1. Что нужно сделать

  1. Написать Java-класс SimulationTicker в пакете simulation.engine.ticker.
  2. Создать переменную для хранения номера текущего часа. При старте программы она должна вычитывать значение из базы данных с помощью репозитория.
  3. Запустить бесконечный цикл в отдельном независимом потоке.
  4. Внутри цикла увеличивать номер часа на 1, рассчитывать час суток (tick % 24) и день недели.
  5. Вызывать метод Диспетчера processActivation, передавая туда объект с рассчитанным временем.
  6. Выдерживать паузу между часами, значение которой брать из настроек приложения (app.simulation.tick-delay-ms).

6. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: МИГРАЦИЯ

Заголовок: Поставка таблицы system_ledger для хранения состояния часов симуляции

6.1. Что нужно сделать

  1. Подготовить SQL-скрипт миграции базы данных (для Liquibase или Flyway).
  2. Скрипт должен создать схему simulation и таблицу system_ledger с первичным ключом.
  3. Добавить команду вставки (INSERT) стартовой строки со значением 0 для ключа CURRENT_SIMULATION_TICK.