Ranked bindings in Sisu are an abstraction of the OSGi service ranking policy (the whole thread-safe dynamic iterator approach is an evolution of the approach I took in peaberry).
Injectors can specify a custom ranking function over their bindings by explicitly binding an implementation of RankingFunction - this is a mapping from a binding to an integer, which lets us rank bindings over a collection of injectors even if they each have a different ranking function. The default RankingFunction is very simple and gives 'default' implementations (ie. those explicitly bound directly to a type, or which are @Named as "default", or whose type starts with Default) a higher ranking based on the primary ranking of the injector. Other implementations are given a lower ranking, again based on the primary ranking of the injector.
The RankingFunction also provides the maxRank available from its mapping - this lets us sort injectors with a RankedSequence before merging and sorting all their bindings. Note that items added to RankedSequence with the exact same ranking are appended with a unique counter to make sure that the sort is stable. RankedSequence itself is very fast and supports concurrent updates while other threads are still iterating over the sequence - updates are immediately reflected in iterators, since the integer-based ranking lets us keep track of their nominal position (the position is only recalculated using binary chop when the sequence mutates and invalidates the iterator's pending position).
This approach has helped us to mimic (and mix) different containers, since Plexus has a different ordering of components to Guice - and will help us merge service-based bindings according to their OSGi service ranking.
|