felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Richard S. Hall" <he...@ungoverned.org>
Subject Re: Dynamically change the bound service
Date Fri, 23 Dec 2011 13:53:32 GMT
On 12/23/11 07:19 , Fabio Fonseca wrote:
> Hi Richard and Clement,
>
> I could finally manage to get back to coding. I have just done what you have
> suggested and everything worked perfectly! Thanks a lot for your help and
> availability!
>
> But I was wondering if there are any mechanism to tell iPOJO to avoid
> creating this cache. I can't see now a reason why someone would like to do
> it, but just as a matter of curiosity. Is this possible?

I'm not sure, but it definitely wouldn't be a good thing to do, since 
you'd need to understand iPOJO's locking protocol and would need to grab 
its locks around all of your service accesses to make sure iPOJO didn't 
change them while you were using them...

-> richard

>
> Thanks!!!
> Fabio
>
>
> clement escoffier wrote:
>> Hi,
>>
>> As explained by Richard, iPOJO uses some advanced caching technics to
>> avoid server switch during an execution flow. So if you have a method
>> using service objects but never return, it will use the same service
>> objects forever. To avoid it, isolate the service manipulation in another
>> method.
>>
>> Regards,
>>
>> Clement
>>
>> On 20.12.2011, at 04:20, Richard S. Hall wrote:
>>
>>> On 12/19/11 21:53 , Fabio Fonseca wrote:
>>>> Hello!
>>>>
>>>> Yes, that you are right! I'm starting a thread in my run() method. I
>>>> have
>>>> just modified my simple consumer + two providers test to remove the
>>>> thread
>>>> and everything worked! Thanks! I only had to create a "super" consumer
>>>> (that
>>>> consumes my consumer) to make it run my consumer's run() method without
>>>> having to stop and start it again. I did that because my objective was
>>>> to
>>>> see the bound provider being changed automatically without the need to
>>>> restart the consumer.
>>>>
>>>> However, I would like to see it working in a second example that uses a
>>>> Thread. I'm still doing some tests with it. I'll post my results here as
>>>> soon as possible.
>>> As I said, it will work with a thread, but you cannot have the thread's
>>> run() methodaccess the services directly, since that method never exits
>>> until the thread exits, so iPOJO will cache the service references the
>>> entire time. If you create some method
>>> MyComponent.doSomethingWithAService() and then call it from your run()
>>> method, then I believe it should work.
>>>
>>> ->  richard
>>>
>>>> Thanks!
>>>> Fabio
>>>>
>>>>
>>>> Richard S. Hall wrote:
>>>>> Overall, it looks not unreasonable.
>>>>>
>>>>> Are you starting a thread? If so, that could be an issue.
>>>>>
>>>>> iPOJO does some sophisticated service reference management to simplify
>>>>> concurrency issues for you. My guess is that iPOJO cannot tell that the
>>>>> thread you've created ever exits the component, so it keeps a cached
>>>>> reference for the lifetime of the thread.
>>>>>
>>>>> Try to modify your thread so that it performs it functionality via a
>>>>> method on the component itself invoked form its run() method...i.e.,
>>>>> your thread should explicitly enter and exit a method block to use a
>>>>> service so that iPOJO can properly keep track of it for you, because
>>>>> iPOJO is likely caching the service reference while your thread runs
in
>>>>> its run() method.
>>>>>
>>>>> To provide a little more detail, when a thread enters a component
>>>>> method, if that method accesses a service field, then iPOJO will
>>>>> automatically cache the service reference for that thread for the
>>>>> entire
>>>>> time that it executes inside that method. This way the thread doesn't
>>>>> have to worry about its service changing in the middle of using it. (Of
>>>>> course, it could still get errors if the service goes away, but that
is
>>>>> normal for OSGi.) In this case, I'm guessing your component has a run()
>>>>> method on the component that access a service, so iPOJO caches the
>>>>> services until the thread exits the run() method, which in your case
>>>>> doesn't happen.
>>>>>
>>>>> ->   richard
>>>>>
>>>>> On 12/18/11 20:49 , Fabio Fonseca wrote:
>>>>>> Hi Richard,
>>>>>>
>>>>>> Thanks for your response. I'd say that's definitely some basic
>>>>>> mistake.
>>>>>> As
>>>>>> you'd said, it is basic behavior (and I was hoping to read that).
The
>>>>>> problem is that I can't find where my mistake is... Yes, I tried
field
>>>>>> injection and I also tried method injection using the bind and unbind
>>>>>> methods in the consumer, but they weren't called when I thought they
>>>>>> should
>>>>>> be.
>>>>>>
>>>>>> The code that I have attached in my original post is my test with
>>>>>> method
>>>>>> injection. I was hoping anybody more experienced than me could find
>>>>>> what
>>>>>> I'm
>>>>>> doing wrong.
>>>>>>
>>>>>> Anyway, in the following lines you can find some parts of the code.
>>>>>> Perhaps
>>>>>> there is something that I'm missing but that is obvious to you.
>>>>>>
>>>>>> . consumer.xml:
>>>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>>>> <iPOJO>
>>>>>>     <component classname="org.test.iPOJO.consumer.Consumer">
>>>>>> 	<requires field="inter" id="Inter">
>>>>>> 	  	<callback transition="bind" method="bindInter"/>
>>>>>>     		<callback transition="unbind" method="unbindInter"/>
>>>>>> 	</requires>
>>>>>>     	<callback transition="validate" method="start"/>
>>>>>>     	<callback transition="invalidate" method="stop"/>
>>>>>>     </component>
>>>>>>     <instance component="org.test.iPOJO.consumer.Consumer"/>
>>>>>> </iPOJO>
>>>>>>
>>>>>> . consumer.java:
>>>>>> public class Consumer
>>>>>> implements Runnable
>>>>>> {
>>>>>> 	private InterfaceOne inter;
>>>>>>
>>>>>> 	public void start() {
>>>>>> 		System.out.println("[Consumer] Validating");
>>>>>> 		run();
>>>>>> 	}
>>>>>>
>>>>>> 	public void stop()	{
>>>>>> 		System.out.println("[Consumer] Invalidating");
>>>>>> 		stopRequestReceiver();
>>>>>> 	}
>>>>>> 	
>>>>>> 	// This was never called
>>>>>> 	public synchronized void bindInter (InterfaceOne i) {
>>>>>> 		System.out.println("[Consumer] Binding");
>>>>>> 	}
>>>>>> 	
>>>>>> 	// This was never called
>>>>>> 	public synchronized void unbindInter (InterfaceOne i) {
>>>>>> 		System.out.println("[Consumer] Unbinding");		
>>>>>> 	}
>>>>>>
>>>>>> 	(...)
>>>>>> }
>>>>>>
>>>>>> . providerA.xml (providerB is similar):
>>>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>>>> <iPOJO>
>>>>>>     <component classname="org.test.iPOJO.providerA.ProviderA">
>>>>>>     	<provides/>
>>>>>>     	<callback transition="validate" method="start"/>
>>>>>>     	<callback transition="invalidate" method="stop"/>
>>>>>>     </component>
>>>>>>
>>>>>>     <instance component="org.test.iPOJO.providerA.ProviderA"/>
>>>>>> </iPOJO>
>>>>>>
>>>>>> . providerA.java:
>>>>>> public class ProviderA
>>>>>> implements InterfaceOne
>>>>>> {
>>>>>> 	private int state = 1;
>>>>>> 	
>>>>>> 	public void start()
>>>>>> 	{
>>>>>> 		System.out.println("[ProviderA] Validating");
>>>>>> 		state = 1;
>>>>>> 	}
>>>>>>
>>>>>> 	public void stop()
>>>>>> 	{
>>>>>> 		System.out.println("[ProviderA] Invalidating");
>>>>>> 		state = 0;
>>>>>> 	}
>>>>>>
>>>>>> 	(...)
>>>>>> }
>>>>>>
>>>>>> Thanks,
>>>>>> Fabio Fonseca
>>>>>>
>>>>>>
>>>>>> Richard S. Hall wrote:
>>>>>>> That doesn't sound right. I'd say there is something else simple
>>>>>>> going
>>>>>>> wrong. If you are using field injection in the consumer, you
could
>>>>>>> look
>>>>>>> to add method injection too to see if you are getting proper
>>>>>>> callbacks
>>>>>>> when services come and go. Regardless, this sounds like pretty
basic
>>>>>>> behavior, so I have to assume there is a simple mistake.
>>>>>>>
>>>>>>> ->    richard
>>>>>>>
>>>>>>> On 12/18/11 5:38 PM, Fabio Fonseca wrote:
>>>>>>>> Hello all,
>>>>>>>>
>>>>>>>> I'm starting to develop my master thesis and this is my first
post
>>>>>>>> to
>>>>>>>> this
>>>>>>>> forum. My research concerns the challenges of developing
>>>>>>>> Self-Adaptable
>>>>>>>> software (software that can change its behavior in response
to a
>>>>>>>> change
>>>>>>>> in
>>>>>>>> its operation context). Right now I'm doing an assessment
aiming to
>>>>>>>> find
>>>>>>>> which technologies are available today that could help achieving
a
>>>>>>>> self-adaptable software.
>>>>>>>>
>>>>>>>> I'm using Apache Felix + iPOJO to develop a simple test.
I have a
>>>>>>>> consumer
>>>>>>>> which wants to consume providers that implement a interface
named
>>>>>>>> InterfaceOne. I have two providers that fits this requirement
(named
>>>>>>>> ProviderA and ProviderB). They all do nothing useful, I am
just
>>>>>>>> trying
>>>>>>>> to
>>>>>>>> produce a self-adaptable behavior.
>>>>>>>>
>>>>>>>> I am using the launcher.jar which is provided with the code
that
>>>>>>>> comes
>>>>>>>> with
>>>>>>>> the great book "OSGi in Action". This launcher creates an
instance
>>>>>>>> of
>>>>>>>> the
>>>>>>>> Felix Framework and loads the bundles found in the bundles/
>>>>>>>> directory
>>>>>>>> passed
>>>>>>>> as a parameter when running the launcher.jar.
>>>>>>>>
>>>>>>>> So I have 4 bundles. Each one of them has an iPOJO component
inside
>>>>>>>> it,
>>>>>>>> except the first one that just has the InterfaceOne interface:
>>>>>>>> . services-1.0.jar
>>>>>>>> . consumer-1.0.jar
>>>>>>>> . providerA-1.0.jar
>>>>>>>> . providerB-1.0.jar
>>>>>>>>
>>>>>>>> The consumer is a simple http listener that uses localhost
port 8080
>>>>>>>> to
>>>>>>>> listen to anything that may appear. When something access
the port
>>>>>>>> 8080,
>>>>>>>> it
>>>>>>>> calls the available provider.
>>>>>>>>
>>>>>>>> When I start the launcher, all bundles are active and OSGi
chooses
>>>>>>>> one
>>>>>>>> of
>>>>>>>> the providers and binds it to the consumer. Using the shell
commands
>>>>>>>> I'm
>>>>>>>> able to stop the providers' bundles and when I do it, the
consumer
>>>>>>>> is
>>>>>>>> invalidated (as per the iPOJO lifecycle).
>>>>>>>>
>>>>>>>> I concluded that when I start the consumer bundle the available
>>>>>>>> provider
>>>>>>>> is
>>>>>>>> bound to the consumer and it remains bound even when I stop
its
>>>>>>>> bundle
>>>>>>>> (in
>>>>>>>> the OSGi lifecycle). The cenario is:
>>>>>>>>
>>>>>>>> - start ProviderA
>>>>>>>> - start Consumer (consumer starts since its dependency is
satisfied)
>>>>>>>> - start ProviderB
>>>>>>>> - stop ProviderA (consumer is still valid in the OSGI's lifecycle,
>>>>>>>> since
>>>>>>>> there is a provider (ProviderB) that satisfy its dependency)
>>>>>>>>
>>>>>>>> At this moment, if I call localhost:8080, the consumer uses
>>>>>>>> ProviderA,
>>>>>>>> even
>>>>>>>> when ProviderA is not available anymore. I conclude that
the binding
>>>>>>>> between
>>>>>>>> Consumer and its provider (which is in this case still the
>>>>>>>> ProviderA)
>>>>>>>> continues to exist even when I stop ProviderA. I read somewhere
that
>>>>>>>> iPOJO
>>>>>>>> lifecycle takes over OSGi's lifecycle, but when I stop ProviderA,
>>>>>>>> the
>>>>>>>> component becames Invalidated (I know because I placed a
method that
>>>>>>>> is
>>>>>>>> called when the provider is invalidated). So, even with the
provider
>>>>>>>> Invalidated, it is still called. I  also read somewhere that
each
>>>>>>>> component
>>>>>>>> is implemented as a Singleton by default, and I have not
changed its
>>>>>>>> behavior. So, I'm lost here. I expected that, in the above
cenario,
>>>>>>>> ProviderB would be called instead of ProviderA.
>>>>>>>>
>>>>>>>> Anyone has a clue that could help me understand how this
mechanism
>>>>>>>> works?
>>>>>>>> Attached you can find a file with all my source code and
ant tasks
>>>>>>>> I'm
>>>>>>>> using
>>>>>>>> to play with iPOJO and OSGi.
>>>>>>>>
>>>>>>>> http://old.nabble.com/file/p32999833/OIA%2BCode.zip OIA+Code.zip
>>>>>>>>
>>>>>>>> Thanks a lot in advance!
>>>>>>>> Fabio Fonseca
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>>
>>>>>>>
>>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>
>>>>>
>>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Mime
View raw message