[ https://issues.apache.org/jira/browse/FELIX-5114?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Pierre De Rop closed FELIX-5114. -------------------------------- > Schedule configuration update in Component executor synchronously > ----------------------------------------------------------------- > > Key: FELIX-5114 > URL: https://issues.apache.org/jira/browse/FELIX-5114 > Project: Felix > Issue Type: Improvement > Components: Dependency Manager > Affects Versions: org.apache.felix.dependencymanager-r5 > Reporter: Pierre De Rop > Assignee: Pierre De Rop > Priority: Minor > Fix For: org.apache.felix.dependencymanager-r6 > > > Currently, all external events are handled through the Component queue > (Executor). This allows to provide a nice thread model, where no > synchronization is required inside DM, and also the user benefits from this > because, because all component lifecycle callbacks and all dependency > injections are also performed using the internal Component queue. So, in some > situation, this model make life easier for the developer. > But there is an exception to all this: the Configuration Dependency is > currently handled from the Configuration Admin dispatcher thread, in other > words, a component update callback can be called while a component "bind" > method is called from another thread (if a service dependency is injected > dynamically from another thread). > We do this because Configuration Admin requires to throw a > ConfigurationException from the update thread, in case there is a > configuration error. > The intent of this issue is simply to stay synchronous (we still throw a > ConfigurationException from the CM update thread), but instead of calling the > component "updated" callback from the CM thread, we schedule the update > callback through the Component internal queue, and we wait for the update > callback to be executed (using a simple Callbable associated with a > FutureTask. > This trick will allow to call the component "updated" callback safely, and > return any configuration errors to the CM update thread. > So, basically, instead of doing this in the > ConfigurationDependencyImpl.updated callback > {code} > try { > invokeUpdated(settings); // either the callback instance or the > component instances, if available. > } catch (ConfigurationException e) { > logConfigurationException(e); > throw e; > } > {code} > then schedule the update invocation in the component executor and wait for > the result like this: > {code} > Callable<ConfigurationException> result = new > Callable<ConfigurationException>() { > @Override > public ConfigurationException call() throws Exception { > try { > invokeUpdated(settings); // either the callback instance > or the component instances, if available. > } catch (ConfigurationException e) { > return e; > } > return null; > } > }; > FutureTask<ConfigurationException> ft = new FutureTask<>(result); > m_component.getExecutor().execute(ft); > > try { > ConfigurationException confError = ft.get(UPDATE_MAXWAIT, > TimeUnit.MILLISECONDS); > if (confError != null) { > logConfigurationException(confError); > throw confError; > } > } > catch (Throwable error) { > logConfigurationException(error); > throw new ConfigurationException(null, "Could not handle > configuration update", error); > } > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332)