This chapter includes the following sections:
Overview of Constraints on Re-Entrant Calls
The Coherence architecture is based on a collection of services. Each Coherence service consists of the Coherence code that implements the service, along with an associated configuration. The service runs on an allocated pool of threads with associated queues that receive requests and return responses.
Re-entrancy, Services, and Service Threads
Dist-Customersinto a distributed service named
Dist-Inventory, or from a distributed service named
Dist-Customersinto a replicated service named
Repl-Catalog. Service names are configured in the cache configuration file using the
This section includes the following topics:
Parent-Child Object Relationships
In the current implementation of Coherence, it is irrelevant whether the "call" is local or remote. This complicates the use of key association to support the efficient assembly of parent-child relationships. If you use key association to co-locate a Parent object with all of its Child objects, then you cannot send an
EntryProcessor to the parent object and have that
EntryProcessor "grab" the (local) Child objects. This is true even though the Child objects are in-process.
To access both a parent object and its child objects, you can do any of the following:
Embed the child objects within the parent object (using an "aggregate" pattern) or,
Use direct access to the server-side backing map (which requires advanced knowledge to do safely), or
Run the logic on another service (for example, Invocation targeted by using
PartitionedService.getKeyOwner), and have that service access the data by using
Place the child objects on another service which would allow reentrant calls (but incur network access since there is no affinity between partitions in different cache services).
Using the aggregate pattern is probably the best solution for most use cases. However, if this is impractical (due to size restrictions, for example), and there is a requirement to access both the parent and child objects without using a client/server model, the Invocation service approach is probably the best compromise for most use cases.
Even when re-entrancy is allowed, one should be very careful to avoid possibly saturating the thread pool and causing catastrophic deadlock. For example, if service A calls service B, and service B calls service A, there is a possibility that enough concurrent calls could use the maximum configured threads in the thread pool, which would cause a form of deadlock. As with traditional locking, using ordered access (for example, service A can call service B, but not vice versa) can help. In addition, relying on the dynamic thread pool can also help.
Service A calling into service A is never allowed
Service A calling into service B, and service B calling back into service A is technically allowed but is deadlock-prone and should be avoided if at all possible.
Service A calling into service B, and service B calling into service C, and service C calling back into service A is similarly restricted
Service A calling into service B is allowed
Service A calling into service B, and service B calling into service C, and service A calling into service C is similarly allowed
A service thread is defined as any thread involved in fulfilling a Coherence API request. Service threads may invoke any of the following entities:
Custom Serialization/Deserialization such as
Backing Map Listeners
Query logic such as
These entities should never make re-entrant calls back into their own services.