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