Figure 6.10 If a proxied service reappears after disappearing, blocked service calls will resume and com-
plete almost normally. But dependent services will be removed and reregistered, which could allow iter-
ators to traverse them twice.
details of the cheese offer, it checks to see if there are any more offers, and discovers
that a new offer has been added to the list—a cheese offer, apparently. At the end of
the procedure, the reference list still only has two offers, cheese and chocolate, but if
the timing is right (or you insert lots of pauses, as we did!), an unlucky iterator could
see both the old and new occurrences of the cheese offer.
In this case, the only consequence of a potentially disastrous outage of the persis-
tence bundle is that the cheese offer is included twice in the printed list of offers. It
looks a bit stupid, but there's no harm done. If iterating over the same service twice is
more serious, you may want to consider making unmodifiable copies of reference lists
before passing them around or iterating over them.
Test, test, test, and test again
In our opinion, this is incredibly cool. We must be honest, though, and disclose that
it took a few tries to get the right pictures! If you expect to support these extreme
dynamics in your application, it's important that you test properly. As you've seen,
hanging on to references to services that might have been compromised can cause
problems (an offer appearing twice). In this case, you might see problems if there
were multiple calls to getOfferFood() from the web frontend that returned different
answers. If you make sure to synchronize access to your sorted list (and return a copy
to the web layer), you should avoid any concurrent modification problems. One more
issue is that if the web frontend holds on to the returned instance from getOffer-
Food() , then it could end up using a stale service.