Wednesday, January 16, 2008

BPEL handling semaphores

General
Semaphores are normally used in low level operating systems to control processes. The mechanism is used to hold-up process. A particular process will not go further if it can not obtain a semaphore. Multiple processes can wait for a single semaphore.

A detailed description of semaphores is written in Wikipedia or in a book that I used decades ago .

Creating BPEL orchestration processes, you basically need semaphores to make sure that a single process can execute a particular task before any other process will do the same. For example; before a message is send by a process to must undergo an initialization or sending a new message. If more then one processes are running, only one process may send this message.

BPEL
In BPEL a semaphore mechanism is implemented. A semaphore handler process is implemented that is running as a singleton.

This process will process messages in a sequence. It keeps track of all the semaphores that will be Acquired or Released. A second process is communicates with this process and the outside world. It can take two operations;
  • Acquire - get a semaphore or wait.
  • Release - release a acquired semaphore.

The name of the two processes are that are created are:
  • Semaphore
  • SemaphoreHandler
The Semaphore process is implemented as a synchronous process. This is explicitly done, because semaphores are meant to be short living. On O/S level, they exist in microseconds. In BPEL I expect this to be milliseconds.

The logical flow of an semaphore is shown as follows.


An BPEL Process will Acquire a semaphore. If this semaphore is available, it 'gets' the semaphore. This means that the BPEL process 'SemaphoreHandler' is keeping track of this. If a second BPEL process wants to acquire the same semaphore, it will not get this semaphore. This process will wait. If the first BPEL process releases the semaphore, the 'SemaphoreHandler' process replies with a 'Release' and the second process gets an 'Acquired'.

An example can be downloaded here.

Steps to implement:

  • Unzip the file in your local directory
  • Start JDeveloper 10.1.3.3
  • Open the workspace.
  • Compile and deploy the to your SOA Suite server:
  • Semaphore
  • SemaphoreHandler
  • SemaphoreTest
To run the application, you must first start the SemaphoreHandler process. Start this process via the '' operation with as payload:
<?xml version = '1.0' encoding = 'UTF-8'?>
<SemaphoreHandlerInitiateRequest xmlns="http://xmlns.oracle.com/SemaphoreHandler">
<SemaphoreHandlerId>SemaphoreHandler/1.0</SemaphoreHandlerId>
</SemaphoreHandlerInitiateRequest>

Initiate the SemaphoreTest process to test Semaphore mechanism.

The Semaphore process can be used via two operations; Acquire and Release. With both operations the name of the Semaphore must be supplied. You must use both operations within the scope of the calling process. The Semaphore detects automatically the process id of his parent process. This process id is used for correlation between "Semaphore" and the "SemaphoreHandler" process. If the "Semaphore" process is called directly, for example via the BPEL console or via SoapUI, there is no parent process. In this case the local process id is used as correlation.

Furthermore, if an semaphore can not be obtained within a specific period, a timeout will occur.

The internal message structure of the "SemaphoreHandler" for holding the semaphores is as follows:

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://xmlns.oracle.com/listOfSemaphores"
targetNamespace="http://xmlns.oracle.com/listOfSemaphores"
elementFormDefault="qualified">
<xsd:element name="listOf-Semaphores" type="listOf-SemaphoresTypes"/>
<xsd:complexType name="listOf-SemaphoresTypes">
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
<xsd:element name="Semaphore" type="SemaphoresTypes" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SemaphoresTypes">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string" minOccurs="1"/>
<xsd:element name="ProcessId" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

In the "SemaphoreHandler" process this XML message is build up. The "Name" is the name of the semaphore while the "ProcessId" is the process id of the calling process "Semaphore". If an semaphore already exist in the list, you can not acquire the semaphore. The acquisition is added to the list. If a release of a semaphore is asked, it can only be done if it exists in the list in combination with the process-Id.

Notes
This solution is working for a non-clustered environment. The current solution is based on a in-memory structure of the semaphores. For a clustered environment, this memory structure must be shared. A solution for this is to hold this structure in Oracle Coherence. This is a shared stored area to keep data in sync over multiple application servers.

The storage is now done in-memory, you could change this to store this somewhere else; like a database table or file or even with Oracle Coherence. This will make the solution more reliable.

Post a Comment