blob: 5ba12ecadc06117e088b3a88de41ba02e340202b [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_74) on Sun Feb 28 20:11:13 CET 2016 -->
<title>ComponentExecutorFactory</title>
<meta name="date" content="2016-02-28">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">
<script type="text/javascript" src="../../../../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="ComponentExecutorFactory";
}
}
catch(err) {
}
//-->
var methods = {"i0":6};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],4:["t3","Abstract Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
var activeTableTab = "activeTableTab";
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../index-all.html">Index</a></li>
<li><a href="../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../../org/apache/felix/dm/ComponentDependencyDeclaration.html" title="interface in org.apache.felix.dm"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../../org/apache/felix/dm/ComponentState.html" title="enum in org.apache.felix.dm"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../../index.html?org/apache/felix/dm/ComponentExecutorFactory.html" target="_top">Frames</a></li>
<li><a href="ComponentExecutorFactory.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a name="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">org.apache.felix.dm</div>
<h2 title="Interface ComponentExecutorFactory" class="title">Interface ComponentExecutorFactory</h2>
</div>
<div class="contentContainer">
<div class="description">
<ul class="blockList">
<li class="blockList">
<hr>
<br>
<pre>public interface <span class="typeNameLabel">ComponentExecutorFactory</span></pre>
<div class="block">A <code>ComponentExecutorFactory</code> service can be registered by any management agent bundle
in order to enable parallel activation of Components.<p>
A <code>ComponentExecutorFactory</code> is part of the new concurrency model that forms the basis
of Dependency Manager 4.0. Let's first give a brief overview of the default thread model used when
no ComponentExecutorFactory is used. Then we'll explain the rationale and the usage of a
<code>ComponentExecutorFactory</code> service.
<p>
<h3>Default Thread Model</h3>
By default, Dependency Manager uses a <b>lock-free/single thread</b> model:
<p><ul>
<li> When an external event that influence the state of a Component is taking place (for example,
when a service dependency on which the Component is depending on is registered in the registry by
a given thread), then DependencyManager does not perform any locking for the handling of the event.
Instead of that, a job that will handle the event is inserted in an internal lock-free
<b><code>Serial Queue</code></b> which is internally maintained in each Component.
<li> all jobs scheduled in the <code>Serial Queue</code> are then executed in FIFO order, by the first
thread which has triggered the first event. This avoid to use some blocking locks in DM internals, and
also it simplifies the development of DM components, because all lifecycle callbacks
(init/start/stop/destroy) and dependency injections are scheduled through the <code>Serial Queue</code>:
This means that your component is not concurrently called in lifecycle callbacks and in dependency injection
methods.
<li> Now let's describe which thread is executing the jobs scheduled in a Component <code>Serial Queue</code>:
When a job (J1) is scheduled in the queue while it is empty, then the current thread becomes the "master"
and will immediately execute the </code>Serial Queue</code> tasks (synchronously). And if another thread
triggers another event concurrently while the "master" thread is executing the job J1, then a job (J2)
for this new event is just enqueued in the <code>Serial Queue</code>, but the other thread returns
immediately to the caller, and the job J2 will then be executed by the "master" thread (after J1).
</ul>
<p>
This mechanism allows to serially handle all Component events (service dependencies) in FIFO order
without maintaining any locks.
<h3>Enabling parallelism with a <code>ComponentExecutorFactory</code></h3>
As described above, all the external events that influence the state of a given component are handed by
jobs scheduled in the <code>Serial Queue</code> of the Component, and the jobs are getting executed serially
by a single "master" thread. So usually, bundles are started from a single thread, meaning that all Components
are then activated synchronously.
<p>
But when you register in the OSGi service registry a <code>ComponentExecutorFactory</code>, that factory
will be used by DependencyManager to create an Executor of your choice for each Component, typically a shared
threadpool configured by yourself. And all the Component <code>Serial Queues</code> will be executed using
the Executor returned by the <a href="../../../../org/apache/felix/dm/ComponentExecutorFactory.html#getExecutorFor-org.apache.felix.dm.Component-"><code>getExecutorFor(Component)</code></a> method.
However, jobs scheduled in the <code>Serial Queue</code> of a given Component are still executed one at a
time, in FIFO order and the Component remains single threaded, and <b>independent Components
may then each be managed and activated concurrently with respect to each other</b>.
<p>
If you want to ensure that all Components are initialized <b>after</b> the ComponentExecutorFactory is
registered in the OSGI registry, you can use the "org.apache.felix.dependencymanager.parallel" OSGi
system property which specifies the list of components which must wait for the ComponentExecutorFactory
service. This property value can be set to a wildcard ("*"), or a list of components implementation class
prefixes (comma separated). So, all components whose class name starts with the specified prefixes will be cached
until the ComponentExecutorFactory service is registered (In this way, it is not necessary to use
the StartLevel service if you want to ensure that all components are started concurrently).
<p>
Some class name prefixes can also be negated (using "!"), in order to exclude some components from the
list of components using the ComponentExecutorFactory service.
<p>
Notice that if the ComponentExecutorFactory itself and all its dependent services are defined using
the Dependency Manager API, then you have to list the package of such components with a "!"
prefix, in order to indicate that those components must not wait for a ComponentExecutorFactory service
(since they are part of the ComponentExecutorFactory implementation !).
<p>
<h3>Examples for the usage of the "org.apache.felix.dependencymanager.parallel" property:</h3>
<blockquote><pre>
org.apache.felix.dependencymanager.parallel=*
-> means all components must be cached until a ComponentExecutorFactory comes up.
org.apache.felix.dependencymanager.parallel=foo.bar, foo.zoo
-> means only components whose implementation class names are starting with "foo.bar" or "foo.zoo"
must be handled using an Executor returned by the ComponentExecutorFactory service. Other Components
will be handled normally, as when there is no ComponentExecutorFactory available.
org.apache.felix.dependencymanager.parallel=!foo.threadpool, *
-> means all components must be delayed until the ComponentExecutorFactory comes up, except the
components whose implementations class names are starting with "foo.threadpool" prefix).
</pre></blockquote>
<h3>Examples of a ComponentExecutorFactory that provides a shared threadpool:</h3>
First, we define the OSGi bundle context system property to enable parallelism for all DM Components
excepts the one which declares the ComponentExecutorFactory:
<blockquote> <pre>
org.apache.felix.dependencymanager.parallel=!com.acme.management.threadpool, *
</pre></blockquote>
Next, here is the Activator which declares the ComponentExecutorFactory:
<blockquote> <pre>
package com.acme.management.threadpool;
import org.apache.felix.dm.*;
public class Activator extends DependencyActivatorBase {
public void init(BundleContext context, DependencyManager mgr) throws Exception {
mgr.add(createComponent()
.setInterface(ComponentExecutorFactory.class.getName(), null)
.setImplementation(ComponentExecutorFactoryImpl.class)
.add(createConfigurationDependency()
.setPid("com.acme.management.threadpool.ComponentExecutorFactoryImpl")));
}
}
</pre></blockquote>
And here is the implementation for our ComponentExecutorFactory:
<blockquote> <pre>
package com.acme.management.threadpool;
import org.apache.felix.dm.*;
public class ComponentExecutorFactoryImpl implements ComponentExecutorFactory {
volatile Executor m_threadPool;
void updated(Dictionary conf) {
m_sharedThreadPool = Executors.newFixedThreadPool(Integer.parseInt("threadpool.size"));
}
&#64;Override
public Executor getExecutorFor(Component component) {
return m_sharedThreadPool; // Use a shared threadpool for all Components
}
}
</pre></blockquote></div>
<dl>
<dt><span class="simpleTagLabel">Since:</span></dt>
<dd>4.0.0</dd>
</dl>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- ========== METHOD SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="method.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t3" class="tableTab"><span><a href="javascript:show(4);">Abstract Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Method and Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code>java.util.concurrent.Executor</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/felix/dm/ComponentExecutorFactory.html#getExecutorFor-org.apache.felix.dm.Component-">getExecutorFor</a></span>(<a href="../../../../org/apache/felix/dm/Component.html" title="interface in org.apache.felix.dm">Component</a>&nbsp;component)</code>
<div class="block">Returns an Executor (typically a shared thread pool) used to manage a given DependencyManager Component.</div>
</td>
</tr>
</table>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ METHOD DETAIL ========== -->
<ul class="blockList">
<li class="blockList"><a name="method.detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a name="getExecutorFor-org.apache.felix.dm.Component-">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>getExecutorFor</h4>
<pre>java.util.concurrent.Executor&nbsp;getExecutorFor(<a href="../../../../org/apache/felix/dm/Component.html" title="interface in org.apache.felix.dm">Component</a>&nbsp;component)</pre>
<div class="block">Returns an Executor (typically a shared thread pool) used to manage a given DependencyManager Component.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>component</code> - the Component to be managed by the returned Executor</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>an Executor used to manage the given component, or null if the component must not be managed using any executor.</dd>
</dl>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../index-all.html">Index</a></li>
<li><a href="../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../../org/apache/felix/dm/ComponentDependencyDeclaration.html" title="interface in org.apache.felix.dm"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../../org/apache/felix/dm/ComponentState.html" title="enum in org.apache.felix.dm"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../../index.html?org/apache/felix/dm/ComponentExecutorFactory.html" target="_top">Frames</a></li>
<li><a href="ComponentExecutorFactory.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a name="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>