Message processing nodes and parsers must work in a multi-instance, multithreaded environment. Many node objects or parser objects are available, each with several syntax elements, and many threads can be executing methods on these objects.
An instance of a message flow processing node is shared and used by all the threads that service the message flow in which the node is defined. Parsers are invoked on the same thread as the nodes, therefore, if the flow is using multiple threads, the parsers are as well.
A user-defined extension must use this model. If a user-defined node requires global data or resources, you must protect the global data or resources by using semaphores to serialize access across threads. However, such serialization can result in performance bottlenecks. Avoid using global data and resources to create a more scalable solution.
The functions implemented by user-defined extensions must be reentrant, and any functions that they invoke must also be reentrant. All user-defined extension utility functions are fully reentrant.
Although a user-defined extension can create additional threads if required, all C utility functions and Java™ methods must be invoked on the same thread that called the cniEvaluate function in C or the evaluate method in Java, as appropriate for the language in which the node is written. If the same thread is not used, your code might compromise the integrity of the broker and cause unpredictable behavior. Any additional threads must not call the user-defined extension API. The API must only be used from the main thread that is invoked by the Broker.
For information about the cniEvaluate function see cniEvaluate.