Hi Peter,
Overall a great article! Thanks for putting this together.
The section on Atomically Closing was confusing. I understand what you are doing in the close(), but don’t see how that has anything to do with unbind and deactivate.
In the section Guarantees from DS -> Ordering, The wording of 3. Activate "Only if all methods are called is the activate method calls” is a bit confusing.
In the section Static References, it would be helpful to explain why you don’t need to use volatile for reference variables and tie it back to your example in the section Time is More Relative than You Think.
In the section Optional References, your example on dynamic references is missing the policy on the @Reference annotation. In this section, you also bring up checking for null, but don’t tie that example specifically to the optional reference. Also, I would add a recommendation and example for using AtomicReference for the dynamic reference.
In the section Tracking Multiple Services when you annotate the volatile List, doesn’t the @Reference annotation need the dynamic policy set, or does DS infer it from the volatile keyword?
In the section Tracking Multiple Services -> Multiple Services per Key, why is the Holder class needed? It seems more straightforward to simply use final ConcurrentMap<String, Set<Foo>> multis = new ConcurrentHashMap<>(). The rest of the logic is unchanged.
In the section IOServer, why doesn’t if (isInterrupted()) call interrupt()?
In the section Asynchronous API’s, why use an OSGi Promise when you can use a CompletableFuture?
That’s it.
Bryan