3ERP

3ERP - простая и бесплатная программа для бухгалтерского и оперативного учёта в учреждениях сферы торговли и услуг, общественного питания, складского хранения, автосервиса, медицины, логистики, производства, управления работами и заявками, поддерживающая до 100 пользователей, на русском языке и полностью бесплатная для 1 пользователя. На сайт (скачать)

11. Расписания и фоновые задачи

11.1. Общая концепция

Платформа поддерживает два типа фонового выполнения:

ТипКлючевое словоНазначениеЗапуск
Периодические задачи РАСПИСАНИЕ Выполнение по расписанию (CRON) Автоматически при старте платформы
Разовые фоновые задачи ВЫПОЛНИТЬ_ФОНОВО Асинхронный вызов процедуры Из любой процедуры или логики

Особенности:

  • Фоновые задачи выполняются параллельно с основным потоком
  • Не блокируют интерфейс пользователя
  • Результаты работы видны только через ВЫВЕСТИ (логи) или изменения в БД

11.2. Расписания (периодические задачи)

Синтаксис:

РАСПИСАНИЕ ИмяРасписания
    КРОН "секунды минуты часы дни месяцы дни_недели"
    ВЫЗВАТЬ Процедура.ИмяПроцедуры
КОНЕЦ_РАСПИСАНИЯ

Формат CRON (6 полей):

┌───────────── секунды (0-59)
│ ┌───────────── минуты (0-59)
│ │ ┌───────────── часы (0-23)
│ │ │ ┌───────────── дни месяца (1-31)
│ │ │ │ ┌───────────── месяцы (1-12)
│ │ │ │ │ ┌───────────── дни недели (0-6, 0 = воскресенье)
│ │ │ │ │ │
* * * * * *

Специальные символы:

уетсяВсе значения
СимволЗначениеПример
** * * * * * — каждую секунду
*/N Каждые N единиц */5 * * * * * — каждые 5 секунд
N Конкретное значение 0 0 9 * * * — в 9:00 каждый день
N-M Диапазон 0 0 9-17 * * * — каждый час с 9 до 17
N,M Несколько значений 0 0 9,12,15 * * * — в 9, 12 и 15 часов

Примеры расписаний:

# Каждые 10 секунд
РАСПИСАНИЕ ПроверкаНовыхЗаказов
    КРОН "*/10 * * * * *"
    ВЫЗВАТЬ Процедура.Заказы.ПроверитьНовые
КОНЕЦ_РАСПИСАНИЯ

# Каждую минуту
РАСПИСАНИЕ ОбновлениеСтатусов
    КРОН "0 * * * * *"
    ВЫЗВАТЬ Процедура.Статусы.ОбновитьПросроченные
КОНЕЦ_РАСПИСАНИЯ

# Каждый час
РАСПИСАНИЕ ЧасовойОтчет
    КРОН "0 0 * * * *"
    ВЫЗВАТЬ Процедура.Отчеты.СформироватьЧасовойОтчет
КОНЕЦ_РАСПИСАНИЯ

# Каждый день в 2 часа ночи
РАСПИСАНИЕ НочнаяОчистка
    КРОН "0 0 2 * * *"
    ВЫЗВАТЬ Процедура.Очистка.УдалитьСтарыеЛоги
КОНЕЦ_РАСПИСАНИЯ

# Каждый понедельник в 9:00
РАСПИСАНИЕ ПонедельничныйОтчет
    КРОН "0 0 9 * * 1"
    ВЫЗВАТЬ Процедура.Отчеты.НедельныйОтчет
КОНЕЦ_РАСПИСАНИЯ

# В рабочие дни (пн-пт) в 18:30
РАСПИСАНИЕ ВечерняяСверка
    КРОН "0 30 18 * * 1-5"
    ВЫЗВАТЬ Процедура.Сверка.СверитьОстатки
КОНЕЦ_РАСПИСАНИЯ

11.3. Фоновый вызов процедур

Синтаксис:

ВЫПОЛНИТЬ_ФОНОВО Процедура.ИмяПроцедуры
ВЫПОЛНИТЬ_ФОНОВО Процедура.ИмяПроцедуры(аргумент1, аргумент2)

Примеры вызова:

# Без аргументов
ПРИ СОХРАНЕНИИ
    ВЫПОЛНИТЬ_ФОНОВО Процедура.ОтправитьУведомление
КОНЕЦ

# С аргументами
ПРИ ПРОВЕДЕНИИ
    ВЫПОЛНИТЬ_ФОНОВО Процедура.СоздатьПлатежку(data.id, data.Сумма)
КОНЕЦ

11.4. Полные примеры

Пример 1: Автоматическое создание задач

ПРОЦЕДУРА Задачи.СоздатьАвтоматическуюЗадачу
    ВЫВЕСТИ "Планировщик: создаю новую задачу"
    
    ВЫЧИСЛИТЬ НоваяЗадача = СОЗДАТЬ("Задачи")
    ЗАПОЛНИТЬ НоваяЗадача.Наименование = "Автоматическая задача от КРОНа"
    ЗАПОЛНИТЬ НоваяЗадача.Статус = "Новая"
    
    ВЫЧИСЛИТЬ Успех = ЗАПИСАТЬ(НоваяЗадача)
    ЕСЛИ Успех ТО
        ВЫВЕСТИ "Создана задача ID: " + НоваяЗадача.id
    КОНЕЦ
КОНЕЦ_ПРОЦЕДУРЫ

РАСПИСАНИЕ ГенераторЗадач
    КРОН "*/30 * * * * *"
    ВЫЗВАТЬ Процедура.Задачи.СоздатьАвтоматическуюЗадачу
КОНЕЦ_РАСПИСАНИЯ

Пример 2: Отправка уведомлений в фоне

ПРОЦЕДУРА Уведомления.ОтправитьОПроведенииЗаказа(ЗаказID)
    ВЫЧИСЛИТЬ Заказ = ПРОЧИТАТЬ("ЗаказНаряд", ЗаказID)
    ВЫЧИСЛИТЬ Клиент = ПРОЧИТАТЬ("Клиенты", Заказ.Клиент)
    
    ПОПЫТКА
        ВЫЧИСЛИТЬ Ответ = HTTP_ЗАПРОС("POST", "https://email-service.com/send", {
            "to": Клиент.Email,
            "subject": "Ваш заказ проведён",
            "body": "Заказ №" + Заказ.Номер + " проведён"
        })
        ВЫВЕСТИ "Уведомление отправлено"
    ИСКЛЮЧЕНИЕ Ошибка
        ВЫВЕСТИ "Ошибка: " + Ошибка
    КОНЕЦ_ПОПЫТКИ
КОНЕЦ_ПРОЦЕДУРЫ

ДОКУМЕНТ ЗаказНаряд
    ЛОГИКА
        ПРИ ПРОВЕДЕНИИ
            ВЫПОЛНИТЬ_ФОНОВО Процедура.Уведомления.ОтправитьОПроведенииЗаказа(data.id)
        КОНЕЦ
    КОНЕЦ
КОНЕЦ

Пример 3: Автоматическое закрытие просроченных заказов

ПРОЦЕДУРА Заказы.ЗакрытьПросроченные
    ВЫВЕСТИ "Проверка просроченных заказов"
    
    ВЫЧИСЛИТЬ Просроченные = НАЙТИ_ВСЕ("ЗаказНаряд", 
        "Статус = 'В работе' AND Дата < date('now', '-14 days')")
    
    ВЫЧИСЛИТЬ Закрыто = 0
    ЦИКЛ ПО Просроченные КАК Заказ
        ЗАПОЛНИТЬ Заказ.Статус = "Автоматически закрыт"
        ВЫЧИСЛИТЬ _ = ЗАПИСАТЬ(Заказ)
        ВЫЧИСЛИТЬ Закрыто = Закрыто + 1
    КОНЕЦ_ЦИКЛА
    
    ВЫВЕСТИ "Закрыто заказов: " + Закрыто
КОНЕЦ_ПРОЦЕДУРЫ

РАСПИСАНИЕ Заказы.НочнаяПроверка
    КРОН "0 0 1 * * *"
    ВЫЗВАТЬ Процедура.Заказы.ЗакрытьПросроченные
КОНЕЦ_РАСПИСАНИЯ

11.5. Важные особенности

1. Фоновые задачи не возвращают результат

# Нельзя получить возврат из фоновой задачи
ВЫЧИСЛИТЬ Результат = ВЫПОЛНИТЬ_ФОНОВО Процедура.Чтото()  # ОШИБКА!

2. Передача аргументов в фоновую задачу

# Передаём примитивные типы
ВЫПОЛНИТЬ_ФОНОВО Процедура.Обработать(ID, "строка", 123)

# В процедуре-получателе
ПРОЦЕДУРА Обработать(ID, Строка, Число)
    ВЫВЕСТИ "Получено: " + ID + ", " + Строка
КОНЕЦ_ПРОЦЕДУРЫ

3. Логирование в фоновых задачах

Весь вывод ВЫВЕСТИ из фоновых задач попадает в лог-файл платформы.

4. Ошибки в фоновых задачах

Фоновая задача не вызовет ошибку в основном потоке. Ошибка будет только в логе.

11.6. Best Practices

  • Не злоупотребляйте частыми расписаниями — CRON "*/1 * * * * *" может создать высокую нагрузку
  • Для длительных операций используйте фоновые задачи — не заставляйте пользователя ждать
  • Логируйте начало и конец работы расписания для отладки
  • Обрабатывайте ошибки внутри фоновых задач — иначе вы не узнаете, что пошло не так
  • Не создавайте расписания, которые могут пересекаться — если задача выполняется дольше интервала, возможны коллизии
  • Используйте флаги для предотвращения параллельного выполнения одной и той же задачи
  • Тестируйте расписания с малыми интервалами при разработке, а в production ставьте реальные значения
3551 | 0 | 3551 | 373 | 187 | 54