Overview

The number of fully concurrent threads per Java Virtual Machine is limited by the number of renderer instances configured for this system.
In a pure pdf renderer setup, the maximum number of instances is 4 (due to limitations when accessing native libraries via JNI). Other renderer engines, such as the InDesign® Server extension, allow configuring an arbitrary number of instances, so in theory an arbitrary number of parallel rendering threads is possible.

There is no linear correlation between the number of instances and number of documents, which can be processed simultaneously, however, there are correlations between the number of instances, documents being opened at the same time, active comet projects and fully parallel Java threads. This document describes the correlations and synchronization impacts.

Java and native / rendering Processing

Parts of the Java Rendering Library functionality is implemented in Java and (usually) not affected by any synchronicity limitations. At the end of this document, you can find an overview of classes / methods and their synchronization impacts.

Partly synchronized Methods

This illustration shows the process flow of a partly or sometimes synchronized method call ("native lib" could also be an external InDesign® Server instance or any other renderer implementation).

The DocumentMetadata.getPreview method can be accessed by several Java threads simultaneously.
If a PDF is already available for this document, previews for one document (e.g. for different spreads) can also be calculated simultaneously by several Java threads.

If the PDF isn't available yet, at least one thread will invoke a renderer operation (createPdf in this case), which is synchronized on renderer instance and document level, i.e.:

Since the same renderer instance can be responsible for other documents, the operation may be blocked by operations taking place on other documents at the sime time.

From the host / client application point of view, synchronization is fully transparent. This means: the Java developer doesn't have to care about concurrency and race conditions. All synchronization is handled internally in the Java Rendering Library.

Also, if a operation requires a certain (native) application state, this is restored before processing the request and all relevant traces of interacting threads is removed.

 

Per Renderer Instance Synchronization

One renderer instance can operate on several documents (OpenedDocument instances) at the same time.

Since document operations rely on a certain renderer application status (e.g. connection to a certain comet project, see below for details), a sequence of commands must be run on this renderer

If two documents processed in different Java thread "share" the same renderer instance, one thread might affect the other for the part of operation utilizing renderer functionality

Again, from the host / client application point of view, this process is fully transparent. This means: the Java developer doesn't have to care about concurrency and race conditions. All grouping and synchronization is handled internally in the Java Rendering Library.

 

Named Connections, Number of Instances, Number of concurrent Threads

There is no limitation regarding the number of registered connections.

Also, one renderer instance can process several documents connected to different projects in parallel. Of course, if operations with these documents overlap, the status required for processing the actual document must be restored. This means: disconnect from the project currently connected to, if it doesn't match the documents connection, and connect to the project appropriate for the document.

"Swapping" connections is a time consuming operation (see illustration). We try to avoid this by delegating requests to renderer instances already connected to the required data source, but if there are more active connections than instances (or, if there are huge differences regarding the expected payload for each connection), the result may not be the best.

In an environment with many different projects, you should try to

 

Operation Grouping

As mentioned before, renderer operation may require some preprocessing and postprocessing, also the Observer pattern allows interception of all renderer operations before and after.

Therefore, a sequence of certain operations is run as an atomic operation as shown in the illustration below.

In plain words, the methods run as an atomic operation include:

The two known (or currently existing) renderer implementations (pdf renderer and InDesign® Server) are not multi threaded (at least not really) or not capable of processing multiple threads concurrently.
Though future rendering implementations may be thread safe and capable of processing multiple threads, we disallow this from the library side to ensure the correct state of the renderer.

A multi threaded renderer - from the library point of view - would be several instances of a renderer, which - in case of the pdf renderer - could be up to four (per JVM) and in case of InDesign® Server the number of InDesign® Server processes started and configured in the application.

Note: in case of the InDesign® Server renderer, we cannot prevent other applications from interacting with a InDesign® Server instance controlled by our Java application.
There is no programmatic way to prevent from this - though this is strictly forbidden. Other applications interacting - no matter, if based on the Java Rendering Library, the priint:comet Plug-Ins for InDesign® Server or third party solutions - would sooner or later leave the renderer instance in an unexpected status and in consequence most probably cause malfunction of our application.
It is subject of the system implementation to ensure, that InDesign® Server is controlled by one application only.

Overview Synchronizaion Impacts of Classes / Methods

This overview is not complete, but shows the most important methods only.

(1) Synchronized Methods (Renderer Factory / Configuration)

These methods are fully synchronized, i.e.: only one thread can enter any of these methods at a time. However, none of these methods (except of connect) implicates too much complexity, they are all expected to return very fast.

(2) Always synchronized Methods (OpenedDocument and derived Objects)

These methods always imply renderer operations. Any of these methods will likely change the status of the document or rely on a (synchronized) status.

Synchronization of these methods takes place on

level.

(3) Sometimes / partly synchronized Methods (OpenedDocument and derived Objects)

See illustration below

Whether executing these methods requires synchronization or not, depends on the situation / status of the affected document. If Metadata resp. PDF is already available for this document, all derived results can be calculated in Java fully parallel.
Synchronization of these methods takes place on level.

(4) Not synchronized Methods

These classes / methods may or may not require synchronization depending on the client requirements.