You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by Brent Daniel <br...@gmail.com> on 2017/04/10 21:39:37 UTC

Modifying service properties in lifecycle and bind methods

Should there be any guarantees on the ordering of service property updates
across methods?

For example, say I have an activate method that simply returns the current
service properties and a bind method that adds "active=true" to the current
properties and returns the updated properties. Both methods are
synchronized.

Let's say activate() is invoked first and exits. Before Felix updates the
service properties, another thread calls the bind method, and Felix updates
the service properties to contain "active=true". Then the first thread
updates the service properties to the set returned from the activate()
method, thus blowing away the changes from the bind method.

Is this a bug? Or should we not be relying on the property updates from the
first method being called taking effect before the second method's updates?

Re: Modifying service properties in lifecycle and bind methods

Posted by David Jencks <da...@gmail.com>.
I opened FELIX-5621 <https://issues.apache.org/jira/browse/FELIX-5621> about this.  I still think returning service properties from event methods cannot be made thread safe.

As noted in the issue, I think ExtComponentContext can be used safely with code like:

final AtomicReference<Dictionary<String, Object>> propRef;

...
  Dictionary<String, Object> oldProps;
  Dictionary<String, Object> newProps;
  do {
    synchronized(propRef) {
      oldProps =  propRef.get();
      newProps = new Hashtable<>(oldProps);
    }
    //update newProps with new information
    extComponentContext.setServiceProperties(newProps);
  } while ( propsRef.compareAndSet( oldProps, newProps)}

I think all we can do in code now is to say not to use the annotation on event methods.

thanks
david jencks

> On Apr 11, 2017, at 9:09 PM, David Jencks <da...@gmail.com> wrote:
> 
> We seem to be thinking along similar lines…. earlier today I wrote this but got distracted before sending:
> 
> At the moment I don’t see how returning the new service properties from bimd/updated/unbind methods can be thread safe.  I think the activate/modify/deactivate methods are ok.
> 
> I wonder if using the ExtComponentContext to modify the properties and synchronizing access would lead to deadlocks.  Better than this would be a compare-and-set method of some sort on ExtComponentContext, perhaps based on a change count
> 
> int cc;
> Dictionary<String, Object> newProps;
> do {
>   cc = etc.getChangeCount();
>  newProps = new Hashtable<>(ecc.getProperties());
>  //update properties
> } while (!ecc.compareAndSet(cc, newProps)}
> 
> david jencks
> 
> 
>> On Apr 11, 2017, at 10:25 AM, Brent Daniel <br...@gmail.com> wrote:
>> 
>> I agree that serializing everything would be counterproductive (though the
>> impact could be reduced by limiting synchronization to methods with the Map
>> return signature.) I wonder if it would be possible to implement a
>> lightweight scheme using update counts, though.
>> 
>> Otherwise it's probably a bad idea to ever have lifecycle and bind methods
>> that both update service properties. And, unfortunately, that may not be
>> all that obvious because the updates will happen in the expected order most
>> of the time. I'm not sure if modifying service properties is documented
>> somewhere (I couldn't find anything), but if it is this should probably be
>> mentioned there.
>> 
>> On Mon, Apr 10, 2017 at 3:28 PM, David Jencks <da...@gmail.com>
>> wrote:
>> 
>>> I don’t think this is a bug.  To avoid this behavior I think we’d have to
>>> serialize all lifecycle method invocations which I believe to be very
>>> undesirable.
>>> 
>>> I could be wrong.
>>> 
>>> david jencks
>>> 
>>>> On Apr 10, 2017, at 2:39 PM, Brent Daniel <br...@gmail.com>
>>> wrote:
>>>> 
>>>> Should there be any guarantees on the ordering of service property
>>> updates
>>>> across methods?
>>>> 
>>>> For example, say I have an activate method that simply returns the
>>> current
>>>> service properties and a bind method that adds "active=true" to the
>>> current
>>>> properties and returns the updated properties. Both methods are
>>>> synchronized.
>>>> 
>>>> Let's say activate() is invoked first and exits. Before Felix updates the
>>>> service properties, another thread calls the bind method, and Felix
>>> updates
>>>> the service properties to contain "active=true". Then the first thread
>>>> updates the service properties to the set returned from the activate()
>>>> method, thus blowing away the changes from the bind method.
>>>> 
>>>> Is this a bug? Or should we not be relying on the property updates from
>>> the
>>>> first method being called taking effect before the second method's
>>> updates?
>>> 
>>> 
> 


Re: Modifying service properties in lifecycle and bind methods

Posted by David Jencks <da...@gmail.com>.
We seem to be thinking along similar lines…. earlier today I wrote this but got distracted before sending:

At the moment I don’t see how returning the new service properties from bimd/updated/unbind methods can be thread safe.  I think the activate/modify/deactivate methods are ok.

I wonder if using the ExtComponentContext to modify the properties and synchronizing access would lead to deadlocks.  Better than this would be a compare-and-set method of some sort on ExtComponentContext, perhaps based on a change count

int cc;
Dictionary<String, Object> newProps;
do {
   cc = etc.getChangeCount();
  newProps = new Hashtable<>(ecc.getProperties());
  //update properties
} while (!ecc.compareAndSet(cc, newProps)}

david jencks


> On Apr 11, 2017, at 10:25 AM, Brent Daniel <br...@gmail.com> wrote:
> 
> I agree that serializing everything would be counterproductive (though the
> impact could be reduced by limiting synchronization to methods with the Map
> return signature.) I wonder if it would be possible to implement a
> lightweight scheme using update counts, though.
> 
> Otherwise it's probably a bad idea to ever have lifecycle and bind methods
> that both update service properties. And, unfortunately, that may not be
> all that obvious because the updates will happen in the expected order most
> of the time. I'm not sure if modifying service properties is documented
> somewhere (I couldn't find anything), but if it is this should probably be
> mentioned there.
> 
> On Mon, Apr 10, 2017 at 3:28 PM, David Jencks <da...@gmail.com>
> wrote:
> 
>> I don’t think this is a bug.  To avoid this behavior I think we’d have to
>> serialize all lifecycle method invocations which I believe to be very
>> undesirable.
>> 
>> I could be wrong.
>> 
>> david jencks
>> 
>>> On Apr 10, 2017, at 2:39 PM, Brent Daniel <br...@gmail.com>
>> wrote:
>>> 
>>> Should there be any guarantees on the ordering of service property
>> updates
>>> across methods?
>>> 
>>> For example, say I have an activate method that simply returns the
>> current
>>> service properties and a bind method that adds "active=true" to the
>> current
>>> properties and returns the updated properties. Both methods are
>>> synchronized.
>>> 
>>> Let's say activate() is invoked first and exits. Before Felix updates the
>>> service properties, another thread calls the bind method, and Felix
>> updates
>>> the service properties to contain "active=true". Then the first thread
>>> updates the service properties to the set returned from the activate()
>>> method, thus blowing away the changes from the bind method.
>>> 
>>> Is this a bug? Or should we not be relying on the property updates from
>> the
>>> first method being called taking effect before the second method's
>> updates?
>> 
>> 


Re: Modifying service properties in lifecycle and bind methods

Posted by Brent Daniel <br...@gmail.com>.
I agree that serializing everything would be counterproductive (though the
impact could be reduced by limiting synchronization to methods with the Map
return signature.) I wonder if it would be possible to implement a
lightweight scheme using update counts, though.

Otherwise it's probably a bad idea to ever have lifecycle and bind methods
that both update service properties. And, unfortunately, that may not be
all that obvious because the updates will happen in the expected order most
of the time. I'm not sure if modifying service properties is documented
somewhere (I couldn't find anything), but if it is this should probably be
mentioned there.

On Mon, Apr 10, 2017 at 3:28 PM, David Jencks <da...@gmail.com>
wrote:

> I don’t think this is a bug.  To avoid this behavior I think we’d have to
> serialize all lifecycle method invocations which I believe to be very
> undesirable.
>
> I could be wrong.
>
> david jencks
>
> > On Apr 10, 2017, at 2:39 PM, Brent Daniel <br...@gmail.com>
> wrote:
> >
> > Should there be any guarantees on the ordering of service property
> updates
> > across methods?
> >
> > For example, say I have an activate method that simply returns the
> current
> > service properties and a bind method that adds "active=true" to the
> current
> > properties and returns the updated properties. Both methods are
> > synchronized.
> >
> > Let's say activate() is invoked first and exits. Before Felix updates the
> > service properties, another thread calls the bind method, and Felix
> updates
> > the service properties to contain "active=true". Then the first thread
> > updates the service properties to the set returned from the activate()
> > method, thus blowing away the changes from the bind method.
> >
> > Is this a bug? Or should we not be relying on the property updates from
> the
> > first method being called taking effect before the second method's
> updates?
>
>

Re: Modifying service properties in lifecycle and bind methods

Posted by David Jencks <da...@gmail.com>.
I don’t think this is a bug.  To avoid this behavior I think we’d have to serialize all lifecycle method invocations which I believe to be very undesirable.

I could be wrong.

david jencks

> On Apr 10, 2017, at 2:39 PM, Brent Daniel <br...@gmail.com> wrote:
> 
> Should there be any guarantees on the ordering of service property updates
> across methods?
> 
> For example, say I have an activate method that simply returns the current
> service properties and a bind method that adds "active=true" to the current
> properties and returns the updated properties. Both methods are
> synchronized.
> 
> Let's say activate() is invoked first and exits. Before Felix updates the
> service properties, another thread calls the bind method, and Felix updates
> the service properties to contain "active=true". Then the first thread
> updates the service properties to the set returned from the activate()
> method, thus blowing away the changes from the bind method.
> 
> Is this a bug? Or should we not be relying on the property updates from the
> first method being called taking effect before the second method's updates?