Потоки и аккаунты
Как модуль Multogram работает в несколько потоков: что такое поток, как раздать аккаунты потокам без повторов, когда задача модуля заканчивается, общие и локальные данные, журнал и статистика задачи, параллельный запуск функций.
Модуль запускается как задача: пользователь заполняет форму модуля, выбирает число потоков и запускает. Каждый поток выполняет функцию Main с начала, независимо от других. Поэтому сценарий модуля пишут так, чтобы каждый поток брал свою часть работы.
Что такое поток
Поток — один независимый проход по сценарию. У каждого потока свои локальные переменные и своя сессия Telegram, поэтому потоки не мешают друг другу. Ошибка в одном потоке завершает только его — остальные работают дальше. Ресурсы — значения формы — у всех потоков общие.
Как раздать аккаунты потокам
Выбранные аккаунты приходят в ресурс accounts одним списком, общим для всех потоков. Чтобы два потока не взяли один аккаунт, поток забирает аккаунт из списка действием Получить значение ресурса с параметром Взять элемент списка: элемент удаляется из списка и отдаётся только этому потоку.
Шаблон нового модуля уже делает это в функции Main:
Получить значение ресурса accounts · First item → [[account]]
WHILE [[account]] != ""
TRY Вызвать функцию ProcessAccount ([[account]])
CATCH Добавить лог «[[account]].phone: ошибка — [[_error]]»
Получить значение ресурса accounts · First item → [[account]]Каждый поток работает, пока в списке есть аккаунты, а потом завершается сам. Так модуль корректно работает при любом числе потоков: если потоков меньше, чем аккаунтов, каждый обработает несколько. Свою работу с аккаунтом добавляйте в функцию ProcessAccount — см. Первый модуль. Тот же приём подходит для любого общего списка — целей, ссылок, строк файла.
Когда задача модуля заканчивается
Как заканчивается задача, задаёт окно Потоки конструктора. Модуль, в котором режим не выбирали, проходит один раз в каждом потоке: задача завершается, когда каждый поток закончил функцию Main. Поток, завершившийся с ошибкой, заново не запускается: аккаунты, которые он не успел взять, заберут другие потоки.
Отсюда правило для своего сценария: Main должна работать, пока есть работа, а не обрабатывать один аккаунт и заканчиваться.
Другой режим можно выбрать в любом модуле:
| Режим | Когда задача заканчивается |
|---|---|
| Непрерывно | Только при ручной остановке: поток, который закончил Main, запускается снова |
| Один проход | Когда каждый поток один раз прошёл Main |
| Число запусков | После N прогонов Main на все потоки вместе |
| До N успешных | Когда N прогонов закончились успешно |
Остановить после ошибок добавляется к любому режиму и завершает задачу после N неудачных прогонов.
Пока поле accounts показано, окно Потоки рекомендует Один проход: аккаунты раздаются один раз, и перезапущенный поток свободных уже не найдёт. Другой режим подходит модулю, который на каждом проходе обходит все аккаунты, не забирая их из списка, или модулю без аккаунтов — с полем accounts, скрытым из формы. Задача в Multogram завершается так же, как запуск кнопкой Запустить в предпросмотре конструктора.
Модуль, который должен работать до ручной остановки (например, следить за чатом), либо крутит цикл внутри Main и не выходит из него, либо работает в режиме Непрерывно.
Данные потоков
| Задача | Чем решать |
|---|---|
| Данные одного аккаунта | Локальные переменные — Установить переменную, результаты действий |
| Общий счётчик для всех потоков | Установить глобальную переменную, Увеличить глобальную переменную |
| Цифры для пользователя: отправлено, ошибок, обработано | Модуль Статистика — индикаторы общие для всех потоков |
| Что происходит в задаче | Добавить лог из модуля Логгер — строки видны в журнале задачи |
| Номер потока, его статус и данные | Модуль Потоки |
| Завершить поток успехом или ошибкой | Завершить поток, Завершить поток с ошибкой |
Сессия — внутри потока
Входите в аккаунт и работайте с ним в одном потоке, а после работы закрывайте сессию действием Destroy Session. Тогда потоки не перехватывают чужие сессии, а сбой одного аккаунта не задевает другие.
Параллельные функции внутри потока
Модуль Задачи запускает функцию в отдельном потоке и не ждёт её завершения — например, чтобы проверить несколько каналов одновременно.
| Действие | Что делает |
|---|---|
| Запустить задачу | Запускает функцию в новом потоке, возвращает ID задачи |
| Ожидать результат | Ждёт завершения задачи (с таймаутом) и получает её результат |
| Проверить завершение, Получить статус задачи | Узнать, закончилась ли задача, не дожидаясь её |
| Отменить задачу | Остановить задачу |
Для обычной работы с аккаунтами это не нужно: потоки модуля уже работают параллельно.
Рекомендации
- Один поток — один аккаунт в каждый момент. Не используйте одну сессию из нескольких потоков.
- Паузы — в ресурсы. Задержку между действиями Telegram выносите в поле формы, чтобы пользователь подбирал её под свои аккаунты — см. Ограничения Telegram.
- Пишите в журнал. Короткая строка на каждый аккаунт — «отправлено», «не удалось войти» — сильно упрощает поиск проблем у пользователя.
Обновлено
Ресурсы и форма модуля
Ресурсы {{name}} в Конструкторе модулей Multogram — поля формы настроек модуля: типы полей, обязательные поля, группы в менеджере макета, условия видимости, переводы, тестовые значения и поле выбора аккаунтов.
Свой код
Модуль «Выполнение кода» в Конструкторе модулей Multogram: встроенный JavaScript, Python, Node.js, CMD, Bash и PowerShell. Как подставляются переменные и ресурсы, как вернуть результат, пакеты.