Ah okay thank you. So you're not talking about the existing Promise class, rather a class that would keep track of the changing state of the service.
As I think you said, that's basically a ServiceTracker. However the existing ServiceTracker class has a lot of complexity and still uses ancient APIs like Dictionary. So the requirement could be to define a new interface ("ServiceHandle"?) that has methods like: interface ServiceHandle<S> { void ifPresent(Consumer<? super S>); // from Optional Stream<S> stream(); // from Optional Promise<S> whenResolved(); Promise<Void> whenUnresolved(); } SCR could inject an instance of this interface into a component (component authors would not be able to instantiate their own instance). It's an interesting idea, but I believe it would be better to keep it as a separate requirement from the "support Optional-typed field injection" requirement. Neil On Wed, 23 Sep 2020 at 14:24, Mark Hoffmann <m.hoffm...@data-in-motion.biz> wrote: > Hi Neil, > > thus is why I said something like a Promise. I think in my first post this > morning I mentioned e.g. the missing unresolve or reresolve. > > On the other side, if we had such an special Object, we could also bring > the feature of callbacks back to field injection. > > Just to get you right, I am not against the idea, I just wanted to get a > step further !? 🙂 > > > Mark Hoffmann > M.A. Dipl.-Betriebswirt (FH) > CEO/CTO > > Phone: +49 3641 384 910 <+49%203641%20384%20910> 0 > Mobile: +49 175 701 2201 <+49%20175%20701%202201> > E-Mail: m.hoffm...@data-in-motion.biz > > Web: www.datainmotion.de > > Data In Motion Consulting GmbH > Kahlaische Strasse 4 > 07745 Jena > Germany > > Geschäftsführer/CEO > Mark Hoffmann > Jürgen Albert > > Jena HRB 513025 > Steuernummer 162/107/05779 > USt-Id DE310002614 > > > -------- Ursprüngliche Nachricht -------- > Von: Neil Bartlett <njbartl...@gmail.com> > Datum: 23.09.20 13:14 (GMT+01:00) > An: Mark Hoffmann <m.hoffm...@data-in-motion.biz> > Cc: OSGi Developer Mail List <osgi-dev@mail.osgi.org> > Betreff: Re: [osgi-dev] SCR: ServiceInjection into Fields that are > Optional<Service> > > Can you clarify how you would expect a Promise to work? > > It sounds a bit like forcing dynamic behaviour into a static reference, > i.e. you get a static field of type Promise which may later resolve to the > bound service. But this disconnects the lifecycle of the component from the > availability of the service. The problem is that the service can change > state many times between available and unavailable, whereas a Promise only > ever has a single state change (from unresolved to resolved). That is, a > Promise cannot revert from resolved to unresolved. > > It seems to me that we already have a mechanism for tracking the dynamic > state of a service with callbacks, and that is method injection. The bind > and unbind methods can be called as many times as necessary. I don't see > how Promises make this any cleaner. > > The idea of explicitly supporting Optional fields does not have any > lifecycle implications for the component. We simply change the > representation of "unbound" from null to Optional.empty() and eliminate a > whole class of potential NPE-throwing code patterns. > > Neil > > On Wed, 23 Sep 2020 at 12:01, Mark Hoffmann <m.hoffm...@data-in-motion.biz> > wrote: > >> Hi, >> >> Neill I see the point. As already mentioned I would rather see something >> like Promise instead fd an Optional, where I could stay with one instance. >> >> In addition to that I would get onResolve out-of-the-box. >> >> Regards, >> >> Mark Hoffmann >> M.A. Dipl.-Betriebswirt (FH) >> CEO/CTO >> >> Phone: +49 3641 384 910 <+49%203641%20384%20910> 0 >> Mobile: +49 175 701 2201 <+49%20175%20701%202201> >> E-Mail: m.hoffm...@data-in-motion.biz >> >> Web: www.datainmotion.de >> >> Data In Motion Consulting GmbH >> Kahlaische Strasse 4 >> 07745 Jena >> Germany >> >> Geschäftsführer/CEO >> Mark Hoffmann >> Jürgen Albert >> >> Jena HRB 513025 >> Steuernummer 162/107/05779 >> USt-Id DE310002614 >> >> >> -------- Ursprüngliche Nachricht -------- >> Von: Neil Bartlett <njbartl...@gmail.com> >> Datum: 23.09.20 11:50 (GMT+01:00) >> An: Mark Hoffmann <m.hoffm...@data-in-motion.biz>, OSGi Developer Mail >> List <osgi-dev@mail.osgi.org> >> Betreff: Re: [osgi-dev] SCR: ServiceInjection into Fields that are >> Optional<Service> >> >> I like Stefan's suggestion and I disagree with some specific points made >> by Mark... responses line below. >> >> On Wed, 23 Sep 2020 at 05:35, Mark Hoffmann via osgi-dev < >> osgi-dev@mail.osgi.org> wrote: >> >>> Hi Stefan, >>> >>> I believe Optionals are not optimal for that. >>> >>> If a service is removed, you would need a new empty optional instance. >>> Optionals doesn't support to hold a state. >>> >> >> The state is in the component, not the Optional instance. References are >> static by default, so under Stefan's example the component would be >> destroyed if the field was bound to a service and that service instance >> became unregistered. The proposed change to the spec is that SCR in this >> case must reinitialize the field with Optional.empty() rather than with >> null. For a dynamic reference, the field would need to be volatile just as >> it is in R7. The only difference is that the field value would be replaced >> by Optional.empty() rather than null in the case where the reference is >> unbound. >> >> There are two advantages that I can see. The first is brevity. When bnd >> sees a field of type Optional, it can infer a cardinality of 0..1, so we do >> not have to annotate with `cardinality=ReferenceCardinality.OPTIONAL`, >> which is more verbose. The second is a thread-safety issue for dynamic >> references. For example, suppose we have a dynamic optional reference in >> R7, i.e.: >> >> @Reference(cardinality=ReferenceCardinality.OPTIONAL, >> policy=ReferencePolicy.DYNAMIC) >> Foo foo; >> >> When we want to use the field value we have to null check first, but the >> following code -- although very clear and intuitive -- is unsafe: >> >> if (foo != null) { >> foo.doSomething(); >> } >> >> It's unsafe because the value of the field can change between the null >> check and the invocation of the method. The following code patterns with a >> field of type Optional<Foo> are safe however: >> >> optFoo.ifPresent(Foo::doSomething) >> >> or: >> >> Stream<String> barNames = optFoo.stream() >> .flatMap(foo -> foo.searchBars("*")) >> .map(Bar::toString); >> >> They are safe because the value of the volatile field is only accessed >> once. >> >> >>> >>> In addition to that you don't have callbacks where to get notified about >>> adding, modifying or removing a service. >>> >> >> We don't have callbacks today with field injection in R7. If you want >> callbacks you need to use method injection. >> >> >>> >>> >>> I could imagine, to get an object similar to the promise injected, that >>> supports the lifecycle callbacks, as well as resolving, unresolving or >>> re-resolving as well as handling cardinality. >>> >>> A fluent API around the OSGi's ServiveTracker could be a solution. >>> Injecting Optional for just a subset of the supported cases in DS would, >>> from my perspective "pollute" the spec. >>> >>> Maybe you can realize a custom solution using ServiceHooks? >>> >> >> I don't think that works because SCR and bnd would both have to >> explicitly understand and support fields of type Optional. >> >> >>> >>> Regards, >>> >>> Mark Hoffmann >>> M.A. Dipl.-Betriebswirt (FH) >>> CEO/CTO >>> >>> Phone: +49 3641 384 910 <+49%203641%20384%20910> 0 >>> Mobile: +49 175 701 2201 <+49%20175%20701%202201> >>> E-Mail: m.hoffm...@data-in-motion.biz >>> >>> Web: www.datainmotion.de >>> >>> Data In Motion Consulting GmbH >>> Kahlaische Strasse 4 >>> 07745 Jena >>> Germany >>> >>> Geschäftsführer/CEO >>> Mark Hoffmann >>> Jürgen Albert >>> >>> Jena HRB 513025 >>> Steuernummer 162/107/05779 >>> USt-Id DE310002614 >>> >>> >>> -------- Ursprüngliche Nachricht -------- >>> Von: Stefan Bischof via osgi-dev <osgi-dev@mail.osgi.org> >>> Datum: 22.09.20 15:48 (GMT+01:00) >>> An: osgi-dev@mail.osgi.org >>> Betreff: [osgi-dev] SCR: ServiceInjection into Fields that are >>> Optional<Service> >>> >>> Hi, >>> >>> I like it to use Optionals if it is possible that a field could be null. >>> >>> >>> In context of OSGi Services with SCR that means I have to handle it like >>> this: >>> >>> ``` >>> >>> @Component >>> public class MyComponent >>> { >>> >>> Optional<Foo> oFoo = Optional.empty(); >>> >>> @Reference(cardinality = ReferenceCardinality.OPTIONAL) >>> void bindFoo(Foo foo) >>> { >>> oFoo = Optional.of(foo); >>> } >>> } >>> >>> ``` >>> >>> What I really want to do is this: >>> >>> ``` >>> >>> @Component >>> public class MyComponent >>> { >>> >>> @Reference >>> Optional<Foo> oFoo; >>> >>> } >>> >>> ``` >>> >>> >>> We have something like this in OSGi - CDI Integration Specification >>> https://youtu.be/7-UUJ4WkMsg?t=839 >>> >>> It would be nice to have this feature with the new version of the R8 DS >>> Spec. >>> >>> >>> Regards >>> >>> Stefan >>> _______________________________________________ >>> OSGi Developer Mail List >>> osgi-dev@mail.osgi.org >>> https://mail.osgi.org/mailman/listinfo/osgi-dev >> >>
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev