Short-lived process and the utilization of native processes

Livecycle uses native processes for Forms and Output related operations, more on this specific topic you can find here.

This blogpost will go into detail about how short-lived processes utilize these native processes and how you can optimize this.

To demonstrate this, I am using the following process.

 

 

 

 

It has a setValue operation, then a renderPDFForm operation and it ends with an executeScript.

The executeScript has the following contents:

System.out.println( “After the render operation” );

In this process, renderPDFForm is using the native process XMLForm. If there is no running XMLForm process when you invoke this process, it will start a new one. What you also can do is to kill the existing processes and then invoke the process and you will also see that the process it started again.

By default you will have a maximum of 4 XMLForm processes running on your system, and these are allocated via a pooling mechanism.

To have more information on this allocation/deallocation process, apply the following setting to your JVM :

-Dcom.adobe.bmc.tracePoolerActivity=true

When you now invoke the process you will something like this in the log :

[com.adobe.service.ResourcePooler] *****http-0.0.0.0-8080-2 trying to obtain lock on com.adobe.service.ResourcePooler@1cf0bb for resource allocation
[com.adobe.service.ResourcePooler] *****http-0.0.0.0-8080-2 allocated ProcessResource@f6b087(name=XMLForm.exe,pid=1392), Pool: {ProcessResource@f6b087(name=XMLForm.exe,pid=1392)=true}, initializing=false, poolsize=1, max=4
[STDOUT] After the render operation
[com.adobe.service.ResourcePooler] *****http-0.0.0.0-8080-2 deallocated ProcessResource@f6b087(name=XMLForm.exe,pid=1392), Pool: {ProcessResource@f6b087(name=XMLForm.exe,pid=1392)=false}, initializing=false, poolsize=1, max=4

So in normal English this would be :
1. Looking for an available XMLForm process
2. Allocating process with pid=1392 for this short-lived process
3. The message from the executeScript
4. Deallocating the process, and returning it back to the pool

At first sight you would say this is working as expected, and it is.

But the thing to look for is why the deallocating is taking place AFTER the executeScript.

In a short-lived process the allocation of the native-process is maintained for the whole transaction, this means when the short-lived process has completed the native-process is returned to the pool.

Of course in our example having a simple executeScript will not extend the duration of the lock, but imagine you do send out an email and afterwards execute webservice call.

Having these steps in your process will extend the lock where it doesn’t need to.

What is the impact?

If you are locking the native process longer than needed then you can end up with reaching the maximum number of native process in use. When that happens any subsequent operations that use the native process will have to wait until a native-process is returned back to the pool.

In that case what you will see is that processes are taking longer to complete, but you won’t see an increase of CPU-usage on the machine.

This locking effect on native processes can also lead to a deadlock.  Consider the following process:

Here the process actually uses the XMLForm native process twice, once to render a form, and then, conditionally, an XMLForm native process may be used indirectly to carry out a flatten operation on the form.  What can happen in this instance is that a lock is first obtained during the render, then when the flatten operation is performed indirectly by Assembler, it will attempt to find another different XMLForm native process that is not already locked.  When multiple instances of this process run concurrently, all available native processes can be locked in the first step, with none available to carry out the second step and a deadlock will result.  When this happens the deadlock is eventually broken when the transaction times out.

What is the solution?

What we want to achieve is to return the native-process to the pool as soon as possible, so for example when the render-operation has completed.
The way to do this is to create a wrapper process around renderPDFForm, this wrapper process contains only one step and has a transaction setting “REQUIRES NEW”.

 

 

 

 

This process is now called from the process, instead of doing a call directly to renderPDFForm.

 

 

 

 

If we use this subprocess in our example, then you will see the following output in the logfile:

[com.adobe.service.ResourcePooler] *****http-0.0.0.0-8080-2 trying to obtain lock on com.adobe.service.ResourcePooler@1cf0bb for resource allocation
[com.adobe.service.ResourcePooler] *****http-0.0.0.0-8080-2 allocated ProcessResource@f6b087(name=XMLForm.exe,pid=1392), Pool: {ProcessResource@f6b087(name=XMLForm.exe,pid=1392)=true}, initializing=false, poolsize=1, max=4
[com.adobe.service.ResourcePooler] *****http-0.0.0.0-8080-2 deallocated ProcessResource@f6b087(name=XMLForm.exe,pid=1392), Pool: {ProcessResource@f6b087(name=XMLForm.exe,pid=1392)=false}, initializing=false, poolsize=1, max=4
[STDOUT] After the render operation

As you can see now in the output the native-process is returned back to the pool BEFORE it starts the next step.
The wrapper process has been created for renderPDFForm, but this also applies for the other operations of the FormsService and OutputService.

 

VN:F [1.9.22_1171]
Was this helpful? Please rate the content.
Rating: 10.0/10 (1 vote cast)
Short-lived process and the utilization of native processes, 10.0 out of 10 based on 1 rating

About Feike Visser

Feike is an Adobe Marketing Cloud architect, working for Adobe Consulting in EMEA.
This entry was posted in Adobe LiveCycle ES2 (9.0.x) and tagged . Bookmark the permalink.

5 Responses to Short-lived process and the utilization of native processes

  1. Feike,

    This is a great article. Thanks for this.

    Can you expound a bit on why the native process is held until the end of the short-lived process? If you call renderPDFForm twice in the same short-lived process does it re-use the native process?

    Rob

  2. Feike Visser says:

    hi rob,

    Thank you for your comment.
    The lock is held on the native process because it lasts until the transaction has ended, the transaction ends when the process ends.
    When you call renderPDFForm twice it will re-use the same native-process. Still if you have many steps between the first and second call it is better to use the wrapper process.

    Best,
    Feike

  3. PaulT says:

    Hey Feike,

    Very interesting, do you have any experience of how systems with this type of problem might affect overall throughput – so is there an impact on other short-lived processes that are not using XMLForm,
    Cheers, Paul

    • Feike Visser says:

      hi paul,

      When you have processes that are waiting, then you will have less threads available. The other threads should still be able to be performing as normal.

      Best,
      Feike