[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [gemini-dev] using managed-service-factory inner bean as a reference-listener

Hi Glyn,

Thanks a lot for your explanations. I've been able to achieve my goal using service references. Although this brought along explicit OSGi framework dependencies. But I guess they were coming sooner or later.. :) Thanks again! Your answers were very helpful!

2012/7/13 Glyn Normington <gnormington@xxxxxxxxxx>
See the documentation ([1]) for information on service dynamics and references and collections.

Essentially, if you try to use an extension for which the backing service has gone away, Gemini Blueprint will wait for another backing service to appear. There doesn't seem to be a way of configuring the timeout for this wait on the list element (unlike the reference element which can specify a timeout). Note that the list is managed dynamically, but there is still a race between selecting a member of the list and its backing service going away.

However, reading section 9.2.3.3, it appears you can specify the member-type="service-reference" on the list element to obtain a list of ServiceReference objects. Then you can use the ServiceReference to safely access the backing service ensuring it won't go away while you are calling it.

Regards,
Glyn

On 13 Jul 2012, at 06:34, Alexander Shutyaev wrote:

Hi Glyn,

I was actually unaware of this pattern. I've read the paper and liked the idea very much. Thanks for pointing it out to me :) Moreover, I've actually managed to reference a service list from within an inner bean of managed-service-factory. It turned out to be quite simple:

<osgi:list id="extensions" ... />

<osgix:managed-service-factory ...>
  Â...
  Â<bean ...>
     ...
     <property name="extensions" ref="extensions" />
     ...
  Â</bean>
</osgix:managed-service-factory>

Although I'm a little confused on how do I handle extensions' dynamics this way. You see, the method that makes use of the extensions looks like

public void foo() {
  ÂMyServiceExtension ext = findExtension(extensions, ...);
  Â// extension used here
}

What happens if the extension is unregistered while I still have a reference to it in ext variable? When using bind/unbind methods I know what to do. I assume that bind/unbind methods are called synchronously (at least ServiceListeners according to OSGi spec areÂcalled synchronously) and that means MyService can track usage of an extension and block in unbindÂmethod to postpone its unregistration until the end of the fooÂmethod above. But osgi:list is just a List. I can acquire a reference to its item, and then when the item is removed from the list I'd be in an inconsistent situation.

I believe there is a solution to that which I just don't see or know of. Could you clarify this please? :)

2012/7/13 Glyn Normington <gnormington@xxxxxxxxxx>
Hi Alexander

Why not use a regular whiteboard pattern ([1]) to implement extensibility?

You see I don't understand why you need to know whenÂMyServiceExtension services bind and unbind. It seems quite sufficient to work with the proxies of the MyServiceExtension interfaces, and you can do that much more straightforwardly without resorting to reference-listeners.

Another way of seeing the need for the whiteboard pattern is that the registerExtension/unregisterExtension methods below are effectively creating a "private registry" (discussed in [1]).

You can implement the whiteboard pattern simply in OSGi by passing a <osgi:list> of (proxies to) MyServiceExtension services to each MyService instance. I'm not sure how you would best combine that with the use of managed-service-factory. Any ideas?

Regards,
Glyn
[1]Âhttp://www.osgi.org/wiki/uploads/Links/whiteboard.pdf


From: "Alexander Shutyaev" <shutyaev@xxxxxxxxx>
To: "Gemini and sub-projects developer discussions" <gemini-dev@xxxxxxxxxxx>
Sent: Thursday, 12 July, 2012 5:22:06 PM
Subject: Re: [gemini-dev] using managed-service-factory inner bean as aÂÂÂÂÂÂÂÂreference-listener


Hi Glyn,

Thanks for the answer.ÂOK, maybe there is a more simple solution which I'm not seeing. Let me give you some more details. MyService is a configurable and extensible service. Let me explain these two properties in detail:

1. Configurable. There are mainly 3 (and potentially more) configurations of MyService: a test one, a production one and a special version (for one of the clients). Our application is a multi-userÂenvironment where users use this or that instance of MyService according to the settings. Moreover, these 3 instances of MyService share a lot of common settings.

To achieve this I've decided to use managed-service-factory. We deploy all 3 configurations to ConfigurationAdmin, so we have 3 instances up and in OSGi service registry, and then after importing the right one we can ensure a user uses the right instance.

2. Extensible. Some of MyService's functionality is provided in the form of extensions. I've already mentioned that our application is a multi-user one. The users mentioned are in fact not our users but the users of our customers. So apart from being multi-user our application is also shipped to different customers with a different set of capabilities. That also covers MyService's extensions - some customers have one set of these extensions while the others have some other sets.ÂThe thing to note here is that these extensions are independent of MyService configuration, which means that all 3 (or more) instances of MyService must have the same extension set.

To achieve this I've decided to use OSGi service list:

<osgi:list id="extensions" interface="com.foo.MyServiceExtension">
<osgi:reference-listener bind-method="registerExtension" unbind-method="unregisterExtension" ref="myService" />
</osgi:list>

The idea is that when a new extension registers itself in OSGi service registry all MyService instances should be able to use them.

The problem came, when I tried to achieve both :)

2012/7/12 Glyn Normington <gnormington@xxxxxxxxxx>
Hi Alexander

I'm acting as a "caretaker" project lead for Gemini Blueprint. I've fiddled with the code, but don't profess any significant insights.

I'm confused by the example below. Since the managed-service-factory element can register multiple instances of the myService bean, why would it make sense to reference those instances from the reference-listener which normally expects to drive a single bean?

More generally, it strikes me that this is a bit of an edge case and I'm not convinced that making the Gemini Blueprint externals (even) more complicated would be a wise course of action. I would suggest stepping back and finding some other solution to the real problem. It could even be that Gemini Blueprint is becoming part of the problem here, rather than the solution. ;-)

Regards,
Glyn

On 9 Jul 2012, at 20:16, Alexander Shutyaev wrote:

Hi all!

I've encountered a case which is not yet supported as it seems. Please see the context:

<osgi:list id="extensions" interface="com.foo.MyServiceExtension">
<osgi:reference-listener bind-method="registerExtension" unbind-method="unregisterExtension" ref="???" />
</osgi:list>
<osgix:managed-service-factory id="myServiceFactory" factory-pid="my-service-factory" autowire-on-update="true">
<osgix:interfaces>
<value>com.foo.MyService</value>
</osgix:interfaces>
<bean id="myService" class="com.foo.MyServiceImpl" />
</osgix:managed-service-factory>

where com.foo.Myservice interface has, among others, methods

public void registerExtension(MyServiceExtension extension, Map<?,?> properties);
public void unregisterExtension(MyServiceExtension extension, Map<?,?> properties);

So here's the case. My managed service factory is registering bean instances of MyService, and I need to use these bean instances as reference listeners (so that they can obtain MyServiceExtensions). The problem is what to put in the refÂattribute of reference-listener declaraion. There are two possibilities which both turn out wrong:

1. ref="myService" -- fails because myService bean is an inner one, so it's id is not private
2. ref="myServiceFactory" -- fails because myServiceFactory is not a MyServiceÂinstance and thus doesn't have required bind/unbind methods.

Now, I understand that this is not a minor feature request and I am willing to help and write some code, tests etc. All I need is a starting point in source code and a few words on what is the right way to support this functionality.

My proposal is that we use ref="myServiceFactory"Âand the handler (or whatever piece of code does this) treats this case (when ref points to a managed service factory) in a specific way: it waits for MyService instances to be constructed and then does to them whatever he would do if MyService was in a ref in the beginning.

Please feel free to correct my view. And thanks in advance.
_______________________________________________
gemini-dev mailing list
gemini-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/gemini-dev


_______________________________________________
gemini-dev mailing list
gemini-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/gemini-dev



_______________________________________________
gemini-dev mailing list
gemini-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/gemini-dev


_______________________________________________
gemini-dev mailing list
gemini-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/gemini-dev


_______________________________________________
gemini-dev mailing list
gemini-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/gemini-dev


_______________________________________________
gemini-dev mailing list
gemini-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/gemini-dev