Sergey Mikhanov  

On re-entrant SBBs safety (August 12, 2008)

I was always wondering what does “re-entrant” property of SBB mean. SLEE specification warns developer about potential problems related to multithreading (section 6.11):

An SBB Developer can specify that an SBB component is non-reentrant. If an SBB entity of a non-reentrant SBB component is executing in a given transaction context, and another method invocation with the same transaction context arrives for the same SBB entity, the SLEE will throw an exception to the second request. This rule allows the SBB Developer to program the SBB component as single-threaded nonreentrant code.

When one of our SBBs required the loopback call to be possible, I have investigated the different possibilities for the potential error here. It all boils down to the possibility for SBB to hold some custom state (for stateless objects re-entrant invocations from multiple threads are safe) and to the concurrency control of the event delivery. In our case the dependencies between two SBBs could be depicted as below. Note that I am using create stereotype everywhere, implying that SBB entity for SBB A is created during the process of initial event delivery, and SBB entity for SBB B is created after invocation of ChildRelation.create() method. We will see below that this simplification does not influence the final conclusion.

Local SBB invocations sequence diagram

The actual details of the local method invocations (probably involving proxies) at steps 12 and 13 are omitted. Two questions arise here:

  • Is the invocation at step 13 delivered to the same SBB object (remember the mentioned proxies)?
  • Is the state of this object the same as before the invocation?

The answer for the first question is “we don’t actually care”. Section 2.2.7 of the SLEE specification says that “the SLEE may assign zero or more SBB objects to represent an SBB entity”, but 6.5.1 prohibits using of class fields for storing local object state. This means that even if the invocation 13 is delivered to another SBB object (and here we are coming to the answer for the second question), then its state would be the same.

But this is not all. A more complicated situation may occur if:

  • SLEE delivers an event in another thread to the same SBB entity somewhere between steps 12 and 13
  • …and has chosen for this delivery the same SBB object as for invocation 13
  • …and this SBB object is different from the object used for delivery of event Foo (section 8.6.6 guarantees serial invocation order only for event handlers for events delivered in the same Activity Context).

In accordance with section 8.6.6, SLEE guarantees that invocations of any methods on the same SBB object are always serial (i.e. are never overlapping). Therefore, event handler will finish its work before step 13, thus (potentially) changing SBB entity state.

We could conclude the simple rules for re-entrant SBBs:

  • Event handlers not changing SBB entity state are always safe for re-entrant SBBs (though local methods invocation could change state)
  • If underlying resource (say, network) guarantees event firing order, and latter event handlers do not modify SBB entity state required by former, then this is also safe

I was unable to find any other possible problems with re-entrant SBBs, but readers from jNetX and OpenCloud (I know, there are some) are always welcome to prove me wrong.