Описание процесса печати

Рассмотрим всю цепочку, которую проходит задание на печать.

1. Пользователь вызывает функцию печати на сервере приложений. Печать может быть:

синхронная (обычная) – в этом случае:

выполняется обработчик, который сразу же вычисляет и создает объект с данными для печатной формы;

при этом клиент ожидает завершения работы этого обработчика;

асинхронная (отложенная) – в этом случае данные будут сформированы позднее.

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

Прикладной разработчик может использовать асинхронную печать в том случае, когда он уверен, что по факту отложенного формирования данных для печати, пользователь все равно получит необходимый результат. Например, асинхронно можно напечатать документ отгрузки товара на склад, когда статус заказа изменится на "оплачено".

2. Сервер приложений сохраняет задание в базе данных на сервере Oracle.

3. Все сервера приложений, которым это разрешено соответствующими настройками, обращаются к серверу базы данных и отправляют полученные от него задания на сервис печати (Print Service).

Oracle группирует все поступающие на печать задания по принтерам, на которые они были отправлены, и, игнорируя очередность их поступления, раздает задания обращающимся к нему серверам приложений последовательно для каждого из принтеров. Однако в очереди на каждый конкретный принтер задания раздаются уже в порядке их поступления – первым отсылается первое поступившее на печать задание, затем второе и т.д. Разбиение одной общей очереди печати на очереди по принтерам реализовано для того, чтобы принтеры не простаивали без работы. Это может случиться в том случае, когда, на один загруженный принтер попадает последовательно большое количество заданий, например, сто, а затем на печать отправляется сто первое задание на другой – простаивающий принтер, которому в случае общей очереди пришлось бы ожидать отправки предыдущих ста заданий.

Задания могут печататься пакетами. Это реализовано для случаев, когда нужно распечатать несколько печатных форм на один принтер и чтобы при этом заданная последовательность печати не была нарушена другими вклинившимся заданиями. Пакет заданий всегда будет печататься в предопределенной последовательности в независимости от очередности поступления на печать заданий пакета.

Если данные для печати не были рассчитаны сразу (случай асинхронной печати), перед оправкой на Print Service сервер приложений их вычислит. Сервер базы данных раздает такие задания только тем серверам приложений, которым операция расчета разрешена соответствующими настройками.

В случае удачной отправки задания на Print Service оно удаляется из базы данных.

4. Print Service принимает задания от сервера приложений и распределяет их по менеджерам печати (Print Manager):

PrintServer

Для каждого принтера запускается отдельный Print Manager, который работает с заданиями на печать только на этот принтер. Если Print Service не находит Print Manager для какого-либо принтера (задание на принтер отсылается впервые с момента запуска Print Service) он создает новый Print Manager.

Все менеджеры печати и Print Service работают в рамках одного сервиса на сервере печати.

Каждый Print Manager:

хранит локально в файле собственную очередь заданий на печать. Это позволяет восстановить задания на печать в случае сбоя и перезапуска сервиса печати;

отсылает задание на принтер через отдельный специальный процесс Print Worker;

задания хранятся в очереди до тех пор, пока Print Worker не напечатает их;

Print Worker – это отдельный процесс, который:

имеет свою собственную очередь заданий, которые отсылаются на печать в порядке их поступления на Print Worker – первым отсылается первое поступившее на печать задание, затем второе и т.д.;

строит (рендерит) печатную форму;

отсылает созданную форму на принтер;

непосредственно работает с драйвером принтера.

Каждое задание перед печатью рендерится. На это действие требуется определенное количество времени, в процессе которого принтер бездействует. Чтобы принтер по возможности не простаивал, рендеринг заданий возможен в отдельных дополнительных потоках. Основной поток получает очередное задание и рендерит его, только если этого еще не было сделано дополнительным потоком, после чего отсылает на печать.

Print Service управляет выделением дополнительных потоков пропорционально загрузке процессов Print Worker. Число дополнительных потоков, которым управляет Print Service, определяется параметром AdditionalThreadsCount в файле его конфигурации.

На процесс рендеринга задан таймаут, величина которого определяется в файле конфигурации Print Service параметром TaskBuildingTimeOut. По истечении этого таймаута задание на печать переходит в невалидное состояние и удаляется из очередей Print Worker и Print Manager. Пользователю, который отправил задание, отсылается уведомление о невозможности его напечатать.

На процесс непосредственно печати также задан таймаут. Величина таймаута печати одной страницы определяется в файле конфигурации Print Service параметром PagePrintingTimeOut. Величина таймаута печати задания пропорциональна количеству страниц в нем и равна произведению [количество страниц задания]*[количеств копий печати]*[величина таймаута]. По прошествии таймаута, если печать не завершилась, Print Service перезапускает соответствующий процесс Print Worker.

Смысл выделения Print Worker в отдельный процесс как раз и состоит в возможности его перезапуска при зависании драйвера принтера без потери заданий печати и перезапуска всего сервиса печати. В случае перезапуска Print Worker, Print Manager заново отправляет ему очередь заданий.