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

Reply via email to