Перейти к основному содержимому
Версия: 7.0

Оператор NEWEXECUTOR

Оператор NEWEXECUTOR - создание действия, позволяющего выполнение других действий в новой службе выполнения — серверном пуле потоков либо клиентском диспетчере.

Синтаксис

NEWEXECUTOR action THREADS threadExpr [syncType]
NEWEXECUTOR action CLIENT connectionExpr [syncType]

где syncType имеет один из следующих вариантов:

WAIT [timeoutExpr]
NOWAIT

Описание

Оператор NEWEXECUTOR создает действие, внутри которого все NEWTHREAD диспетчеруются созданной этим оператором службой выполнения. В режиме THREADS служба представляет собой серверный пул потоков заданного размера: тело каждого вложенного потока разделяет сессию изменений с вызывающим кодом, а NEWTHREAD ... SCHEDULE использует серверный планировщик. В режиме CLIENT служба — это клиентский диспетчер на указанном соединении: действия вложенных потоков доставляются на это соединение и исполняются на сервере приложений в собственной свежей сессии изменений уровня навигатора этого соединения, не привязанной к какой-либо открытой форме; интерактивные операторы внутри потока направляются в UI этого соединения, а NEWTHREAD ... SCHEDULE использует клиентский таймер.

syncType определяет, дожидается ли оператор завершения вложенных потоков. По умолчанию используется WAIT без тайм-аута: оператор не завершается, пока не завершатся все вложенные потоки, для которых служба регистрирует ожидающий future, после чего значения, записанные через NEWTHREAD ... TO p, применяются в текущей сессии. Форма NEWTHREAD ... CLIENT p без TO future не регистрирует и в ожидание не входит. Если задан тайм-аут ожидания и какие-то потоки в него не уложились, оператор выбрасывает ошибку; значения от потоков, завершившихся ранее, всё равно применяются и видны в окружающем TRY ... CATCH.

Параметры

  • action

    Контекстно-зависимый оператор-действие, описывающий действие, которое будет выполнено.

  • threadExpr

    Выражение, значение которого определяет размер серверного пула потоков. Тип значения — INTEGER. Если значение NULL или 0, размер пула устанавливается равным количеству доступных процессоров сервера.

  • connectionExpr

    Выражение, значение которого определяет соединение, в интерактивный контекст которого будут диспетчеризованы вложенные NEWTHREAD. Возвращаемый класс — SystemEvents.Connection. Если значение NULL (или не разрешается в объект SystemEvents.Connection), оператор завершается без исполнения внутреннего действия и без ошибки.

  • syncType

    Тип синхронизации. Задается одним из ключевых слов:

    • WAIT — синхронное выполнение: оператор дожидается завершения всех вложенных NEWTHREAD, для которых регистрируется ожидающий future, и применяет их TO-результаты. Опционально после WAIT указывается выражение тайм-аута (см. timeoutExpr).
    • NOWAIT — асинхронное выполнение: оператор завершается сразу после диспетча всех вложенных NEWTHREAD. Несовместимо с NEWTHREAD ... TO, которое требует WAIT. NEWTHREAD ... SCHEDULE PERIOD ... требует именно этой формы, так как периодический поток не завершается.

    По умолчанию (без syncType) используется WAIT без тайм-аута.

  • timeoutExpr

    Выражение, значение которого определяет тайм-аут ожидания завершения вложенных потоков в миллисекундах. Тип значения — INTEGER или LONG, значение должно быть строго положительным. Тайм-аут применяется к каждому шагу ожидания и не является строгим общим deadline для всех потоков — при множестве одновременно ожидаемых потоков суммарное время ожидания может оказаться больше заданного.

Примеры

testExecutor {
// Серверный пул из 10 потоков, ожидание завершения
NEWEXECUTOR {
FOR id(Sku s) DO {
NEWTHREAD {
NEWSESSION {
name(s) <- STRING[20](id(s));
APPLY;
}
}
}
} THREADS 10 WAIT;

// Запуск действия на стороне клиента без ожидания
NEWEXECUTOR {
NEWTHREAD MESSAGE 'Привет с клиента';
} CLIENT currentConnection() NOWAIT;

// Сбор результатов из потоков с тайм-аутом ожидания
LOCAL a = INTEGER ();
LOCAL b = INTEGER ();
TRY {
NEWEXECUTOR {
NEWTHREAD { RETURN computeFast(); } TO a;
NEWTHREAD { RETURN computeSlow(); } TO b;
} THREADS 2 WAIT 5000;
} CATCH {
// a / b могут быть заполнены частично, если не все потоки уложились в тайм-аут
MESSAGE 'таймаут: ' + messageCaughtException();
}
}