Don’t get me wrong, your design was bad but you show the key hallmark of a good 
designer! You ‘felt’ the problem and then embarked on a quest to find what the 
problem was.  This intuition and willingness to change are the most important 
traits of good designers. Nobody gets it right the first time.

Kind regards,

        Peter Kriens



> On 14 okt. 2016, at 09:48, Daghan ACAY <daghana...@hotmail.com> wrote:
> 
> Very well said Peter.
> 
> I was suspicious that my design was not good, hence the original message 
> suggests a fundamental revision.
> 
> To my excuse the code started with mandatory single reference to this hell 
> since i was too lazy to rethink the design and try to get away with adding 
> more code (agile?:))
> 
> Thank you all for great insights and let this be a lesson to others. Agile 
> does not mean piling up the code, you need to stop and rethink your design 
> sometime too:)
> 
> Cheers
> Daghan
> 
> Sent by MailWise <http://www.mail-wise.com/installation/2> – See your emails 
> as clean, short chats.
> 
> 
> 
> -------- Original Message --------
> From: Peter Kriens <peter.kri...@aqute.biz>
> Sent: Friday, October 14, 2016 06:37 PM
> To: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
> Subject: Re: [osgi-dev] DS component life cycle.
> 
> I did not say it was impossible … Just that the problem was that the 
> component was not cohesive. Once you have an uncohesive component you tend to 
> create more and more complexity because you have to think of more and more 
> combination of cases. The absolute god send beauty of DS components is that 
> it allows you to create a graph of components where all timing aspects are 
> perfectly defined with hardly seeing any dynamics in your code.
> 
> In your proposal, you have two code paths: before and after the subscription. 
> In my experience this switch over is really hard to get right and usually 
> requires buffering and different code paths. I.e. when I see code like that I 
> get deeply suspicious.
> 
> I learned one thing in OSGi. Once you start ‘fighting’ it you end up in 
> deeper and deeper shit.
> 
> Kind regards,
> 
>         Peter Kriens
> 
> 
> 
> 
> > On 14 okt. 2016, at 09:05, Timothy Ward <tim.w...@paremus.com> wrote:
> > 
> > Peter,
> > 
> > Whilst I agree that using a whiteboard is the right approach, it is 
> > absolutely possible to use the activate method with optional/dynamic 
> > references. 
> > 
> > The issue that you have with activation and dynamic references requires 
> > synchronisation, and a flag to indicate whether the component has 
> > “activated”. Typically you need a synchronised block where you check the 
> > activation state and grab the config, and check this in the bind method. 
> > You also need to handle things that were bound before the activate was 
> > called.
> > 
> > It’s messy, but perfectly possible. 
> > 
> > That said, in general static references are a much simpler and more 
> > reliable approach. Testing threading correctness for dynamic references is 
> > hard, and even if you understand what you’ve written there’s a decent 
> > chance the next developer (probably future you) will curse the next time 
> > they see the code.
> > 
> > Regards,
> > 
> > Tim
> > 
> > 
> >> On 14 Oct 2016, at 07:58, Peter Kriens <peter.kri...@aqute.biz> wrote:
> >> 
> >> @Christian: The MQTT client is optional and dynamic. So the activate 
> >> method cannot be used. You need to subscribe/unsubscribe based on the 
> >> availability of the mqtt server.
> >> 
> >> @Daghan:
> >> 
> >> Divide and conquer! You’re trying to do multiple responsibilities in one 
> >> component and that is the antithesis of modularity, also called lack of 
> >> cohesion. This is a perfect example of how things could get simpler by 
> >> choosing the right decomposition.
> >> 
> >> The best solution imho is to introduce a second,component. Let the Device 
> >> component just be a Device, it should not have to worry about Mqtt. After 
> >> all, you could be connected to other event queues. (It also makes it 
> >> easier to test.) You made mqtt optional to reflect this. This is exactly 
> >> the reason the Whiteboard Pattern was invented!
> >> 
> >> This would look like:
> >> 
> >> 
> >>       @Component( property = “subscriptionChannel=” )
> >>       public class LT100HDeviceImpl implements Device, 
> >> TtnMqttMessageListener {
> >>               // remove the mqtt subscription code but
> >>               // implement the TtnMqttMessageListener
> >>      }
> >> 
> >> And the whiteboard component. Notice the _ in the _mqtt field. This 
> >> ensures it is set before the event method that has a name that will appear 
> >> in a sorted list later. (References are sorted by name.) (I vaguely recall 
> >> field references are done before bind methods but this makes it certain.)
> >> 
> >>       @Component(immediate=true)
> >>       public class MQTTWhiteboard {
> >> 
> >>               @Reference
> >>               TtnMqttProtocol _mqtt;
> >> 
> >>               @Reference( cardinality = ReferenceCardinality.OPTIONAL, 
> >> policy = ReferencePolicy.DYNAMIC )
> >>               void addMqttListener( TtnMqttMessageListener l, 
> >> Map<String,Object> props ) {
> >>                       String channel = props.get( “subscriptionChannel” );
> >>                       if ( channel != null && !channel.isEmpty() ) {
> >>                               _mqtt. subscribe( channel, l );
> >>               }
> >> 
> >>               void removeMqttListener( TtnMqttMessageListener l, 
> >> Map<String,Object> props ) {
> >>                       String channel = props.get( “subscriptionChannel” );
> >>                       if ( channel != null && !channel.isEmpty() ) {
> >>                               _mqtt.unsubscribe( channel );
> >> 
> >>               }
> >>       }
> >> 
> >> You now created a whiteboard service that can also be used by other Device 
> >> implementations while significantly reducing the complexity of your 
> >> implementation. 
> >> 
> >> This is why after all those years I still love OSGi … you can only do this 
> >> when you have dynamic components. As your struggle showed, trying to 
> >> manage this is quickly becoming quite complex. Whenever you enter in such 
> >> a struggle, think, lack of cohesion is often your problem.
> >> 
> >> Kind regards,
> >> 
> >>       Peter Kriens
> >> 
> >> 
> >>> 
> >>> On 14 okt. 2016, at 08:09, Christian Schneider <ch...@die-schneider.net> 
> >>> wrote:
> >>> 
> >>> In your case simply inject the ttnMqttClient in the @Reference and do the 
> >>> subscribe in @Activate when you get the config and the unsubscribe in 
> >>> @Deactivate.
> >>> 
> >>> Christian
> >>> 
> >>> 2016-10-13 23:00 GMT+02:00 Daghan ACAY <daghana...@hotmail.com>:
> >>> Hi all,
> >>> 
> >>> I am trying to create a component that is instantiated by ConfigAdmin and 
> >>> uses multiple references to operate. Basically the component should 
> >>> instantiate through a factory configuration and use that configuration to 
> >>> set up its own @Reference s. You can see the code here:
> >>> 
> >>>https://github.com/daghanacay/com.easyiot.device/blob/master/com.easyiot.LT100H.device.provider/src/com/easyiot/LT100H/device/provider/LT100HDeviceImpl.java
> >>> 
> >>><https://github.com/daghanacay/com.easyiot.device/blob/master/com.easyiot.LT100H.device.provider/src/com/easyiot/LT100H/device/provider/LT100HDeviceImpl.java>
> >>> 
> >>> All the mentioned @Reference ed components are instantiated by 
> >>> configuration as well, so at a given time the @Reference might not be 
> >>> available but my own component should still work. yet should the 
> >>> Reference available then it should be injected, basic 0-1 strategy.
> >>> 
> >>> Problem I am facing with the current form of the code is that, the 
> >>> @Reference injection is happening before the @Activate method is called. 
> >>> This leads to NPE in the @Reference method due to null configuration. Is 
> >>> it possible to make this code work such that config is provided to the 
> >>> component before the dependency injection?
> >>> 
> >>> I have tried annotating the class fields and set them "volatile". I even 
> >>> make them a list and use the class fields in the activate method this 
> >>> time the class fields were null due to 0-1 strategy. so I end up with 
> >>> annotating the methods.
> >>> 
> >>> I might have designed this all wrong, so any help simple or fundamental 
> >>> is appreciated.
> >>> 
> >>> Regards
> >>> 
> >>> -Daghan
> >>> 
> >>> Sent by MailWise – See your emails as clean, short chats.
> >>> 
> >>> 
> >>> _______________________________________________
> >>> OSGi Developer Mail List
> >>> osgi-dev@mail.osgi.org
> >>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
> >>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
> >>> 
> >>> 
> >>> 
> >>> -- 
> >>> -- 
> >>> Christian Schneider
> >>> http://www.liquid-reality.de <http://www.liquid-reality.de/>
> >>> 
> >>> Open Source Architect
> >>> http://www.talend.com <http://www.talend.com/>
> >>> _______________________________________________
> >>> OSGi Developer Mail List
> >>> osgi-dev@mail.osgi.org
> >>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
> >>> <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 
> >> <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 
> > <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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to