blob: 05622f729be57aa578d1a801571d6c929832b22e [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<link rel="shortcut icon" href="http://aries.apache.org/images/favicon.ico"></link>
<link type="text/css" rel="stylesheet" href="http://aries.apache.org/resources/site.css"></link>
</script><script src="http://aries.apache.org/resources/menus.js" language="javascript" type="text/javascript"></script>
<meta name="keywords" content="..."/>
<meta name="description" content="..." />
<title>
Apache Aries -
</title>
</head>
<body onload="SetMenu()">
<table width="100%" cellpadding="0" cellspacing="0">
<tr width="100%">
<td id="cell-0-0" colspan="2">&nbsp;</td>
<td id="cell-0-1">&nbsp;</td>
<td id="cell-0-2" colspan="2">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-1-0">&nbsp;</td>
<td id="cell-1-1">&nbsp;</td>
<td id="cell-1-2">
<div style="padding: 5px;">
<div id="banner">
<!-- Banner -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" class="topbardiv" nowrap="">
<a href="http://aries.apache.org/" title="Apache Aries"> <img border="0" src="http://aries.apache.org/images/Arieslogo_Horizontal.gif"> </a>
</td>
<td align="right" nowrap="">
<a href="http://www.apache.org/" title="The Apache Software Foundation"> <img border="0" src="http://aries.apache.org/images/apache_feather.png"> </a>
</td>
</tr>
</table>
<!-- Banner -->
</div>
</div>
<div id="top-menu">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tr>
<td>
<div align="left">
<!-- Breadcrumbs -->
<!-- Breadcrumbs -->
</div>
</td>
<td>
<div align="right">
<!-- Quicklinks -->
<DIV style="padding: 5px 5px 0px 25px;">
<FORM action="http://www.google.com/search" method="get" style="font-size: 10px;">
<A href="http://www.apache.org/licenses/LICENSE-2.0.html" class="external-link" rel="nofollow">License</A>
<INPUT name="ie" type="hidden" value="UTF-8"></INPUT>
<INPUT name="oe" type="hidden" value="UTF-8"></INPUT>
<INPUT maxlength="255" name="q" size="15" type="text" value></INPUT>
<INPUT name="btnG" type="submit" value="Search"></INPUT>
<INPUT name="domains" type="hidden" value="aries.apache.org"></INPUT>
<INPUT name="sitesearch" type="hidden" value="aries.apache.org"></INPUT>
</FORM>
</DIV>
<!-- Quicklinks -->
</div>
</td>
</tr>
</table>
</div>
</td>
<td id="cell-1-3">&nbsp;</td>
<td id="cell-1-4">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-2-0" colspan="2">&nbsp;</td>
<td id="cell-2-1">
<table>
<tr height="100%" valign="top">
<td height="100%">
<div id="wrapper-menu-page-right">
<div id="wrapper-menu-page-top">
<div id="wrapper-menu-page-bottom">
<div id="menu-page">
<!-- NavigationBar -->
<style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<div onclick="SwitchMenu('documentation')" id="documentationTitle" class="menutitle">Documentation</div>
<div id="documentation" class="menuitemgroup">
<div class="menuitem">
<a href="/documentation/integrators-guide.html">Integrators Guide</a>
</div>
<div class="menuitem">
<a href="/documentation/articles.html">Articles</a>
</div>
<div class="menuitem">
<a href="https://svn.apache.org/repos/asf/aries/slides/">Slides</a>
</div>
<div class="menuitem">
<a href="/documentation/tutorials.html">Tutorials</a>
</div>
<div class="menuitem">
<a href="/documentation/tools.html">Tools</a>
</div>
</div>
<div onclick="SwitchMenu('modules')" id="modulesTitle" class="menutitle">Modules</div>
<div id="modules" class="menuitemgroup">
<div class="menuitem">
<a href="/modules/samples.html">Samples</a>
</div>
<div class="menuitem">
<a href="/modules/async-svcs.html">Asynchronous Services</a>
</div>
<div class="menuitem">
<a href="/modules/blueprint.html">Blueprint</a>
</div>
<div class="menuitem">
<a href="/modules/blueprint-maven-plugin.html">Blueprint-maven-plugin</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintannotation.html">Blueprint Annotations</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintnoosgi.html">Blueprint No-OSGi</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintweb.html">Blueprint Web</a>
</div>
<div class="menuitem">
<a href="/modules/containers.html">Containers</a>
</div>
<div class="menuitem">
<a href="/modules/esaanttask.html">ESA Ant Task </a>
</div>
<div class="menuitem">
<a href="/modules/ebamavenpluginproject.html">EBA Maven Plugin </a>
</div>
<div class="menuitem">
<a href="/modules/esamavenpluginproject.html">ESA Maven Plugin </a>
</div>
<div class="menuitem">
<a href="/modules/jmx.html">JMX</a>
</div>
<div class="menuitem">
<a href="/modules/jndiproject.html">JNDI</a>
</div>
<div class="menuitem">
<a href="/modules/jpaproject.html">JPA</a>
</div>
<div class="menuitem">
<a href="/modules/transactioncontrol.html">Transaction Control Service</a>
</div>
<div class="menuitem">
<a href="/modules/transactionsproject.html">Transactions</a>
</div>
<div class="menuitem">
<a href="/modules/rsa.html">Remote Service Admin (RSA)</a>
</div>
<div class="menuitem">
<a href="/modules/spi-fly.html">SPI Fly</a>
</div>
<div class="menuitem">
<a href="/modules/subsystems.html">Subsystems</a>
</div>
<div class="menuitem">
<a href="/modules/applications.html">Applications (obsolete)</a>
</div>
</div>
<div onclick="SwitchMenu('downloads')" id="downloadsTitle" class="menutitle">Downloads</div>
<div id="downloads" class="menuitemgroup">
<div class="menuitem">
<a href="/downloads/currentreleases.html">Current Releases</a>
</div>
<div class="menuitem">
<a href="/downloads/testresults.html">Compliance Tests</a>
</div>
<div class="menuitem">
<a href="/downloads/archived-releases.html">Archived Releases</a>
</div>
</div>
<div onclick="SwitchMenu('community')" id="communityTitle" class="menutitle">Community</div>
<div id="community" class="menuitemgroup">
<div class="menuitem">
<a href="/community/resources.html">Community Resources</a>
</div>
<div class="menuitem">
<a href="/community/gettinginvolved.html">Getting Involved</a>
</div>
<div class="menuitem">
<a href="/community/people.html">Who we are</a>
</div>
<div class="menuitem">
<a href="/community/boardreports.html">Board Reports</a>
</div>
<div class="menuitem">
<a href="/community/logos.html">Logos for Users</a>
</div>
</div>
<div onclick="SwitchMenu('development')" id="developmentTitle" class="menutitle">Development</div>
<div id="development" class="menuitemgroup">
<div class="menuitem">
<a href="/development/buildingaries.html">Building Aries </a>
</div>
<div class="menuitem">
<a href="/development/guidelines.html">Cording Guidelines</a>
</div>
<div class="menuitem">
<a href="/development/architecture.html">Architecture</a>
</div>
<div class="menuitem">
<a href="/development/releasingaries.html">Releasing Aries </a>
</div>
<div class="menuitem">
<a href="/development/compliancetesting.html">OSGi Compliance Tests </a>
</div>
<div class="menuitem">
<a href="/development/maintainingthewebpages.html">Web Site Maintenance </a>
</div>
</div>
<div onclick="SwitchMenu('sponsorship')" id="sponsorshipTitle" class="menutitle">Sponsorship</div>
<div id="sponsorship" class="menuitemgroup">
<div class="menuitem">
<a href="http://www.apache.org/foundation/thanks.html">Thanks</a>
</div>
<div class="menuitem">
<a href="http://www.apache.org/foundation/sponsorship.html">Sponsoring Apache</a>
</div>
</div>
<div class="promotion">
<a href="http://www.apache.org/events/current-event.html">
<img src="http://www.apache.org/events/current-event-125x125.png" width="125" height="125"/>
</a>
</div>
<!-- NavigationBar -->
</div>
</div>
</div>
</div>
</td>
<td height="100%" width="100%">
<!-- Content -->
<div class="wiki-content"><style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<p>Title: Asynchronous Services</p>
<h1 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">&para;</a></h1>
<p>The R6 OSGi specifications include support for Asynchronous programming using OSGi services.
Apache Aries aims to provide small, compliant implementations of these specifications to enable asynchronous
programming in enterprise applications. The two key specifications are OSGi Promises and the Async service.</p>
<h1 id="osgi-promises">OSGi Promises<a class="headerlink" href="#osgi-promises" title="Permanent link">&para;</a></h1>
<p>One of the fundamental pieces of an asynchronous programming system is the <em>Promise</em>. A Promise is a holder type that
represents an asynchronous calculation or computation. Since Java 5 the JDK has contained <em>java.util.concurrent.Future</em> to perform this
function. Java's Future type is, however, fatally flawed as it has no callback to notify the user when it resolves. Instead the
user must make a blocking call to <em>get()</em>.</p>
<p>OSGi promises fix this problem by defining a Promise interface which allows the user to register callbacks which will be
called when the promise <em>resolves</em>. These callbacks are lambda friendly SAM types, but the Promise API itself has no
dependencies on Java 8. The Aries version (org.apache.aries.async.promise.api) has a minimum requirement of JDK 6.</p>
<h2 id="creating-osgi-promises">Creating OSGi Promises<a class="headerlink" href="#creating-osgi-promises" title="Permanent link">&para;</a></h2>
<p>Creating a Promise is easy. The <em>org.osgi.util.promise.Deferred</em> type is a factory for a single promise, and can also be used to
resolve or fail the promise:</p>
<div class="codehilite"><pre><span class="n">Deferred</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">deferred</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Deferred</span><span class="o">&lt;&gt;</span><span class="p">();</span>
<span class="n">new</span> <span class="n">Thread</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">int</span> <span class="n">result</span> <span class="p">=</span> <span class="n">calculateReallyHardSum</span><span class="p">();</span>
<span class="n">deferred</span><span class="p">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
<span class="p">}).</span><span class="n">start</span><span class="p">();</span>
<span class="n">Promise</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">p</span> <span class="p">=</span> <span class="n">deferred</span><span class="p">.</span><span class="n">getPromise</span><span class="p">();</span>
<span class="p">...</span>
</pre></div>
<p>But wait - what if something goes wrong? How do we signal to the user that there was a problem and the result is never coming?
The answer is very easy - Promises have the concept of <em>failure</em>. A promise will <em>either</em> resolve <em>or</em> fail at most once. For well
written code this rule is usually the same as "A promise will either resolve or fail <em>exactly</em> once". Promises are thread safe and
effectively immutable, meaning they can be shared with other code.</p>
<div class="codehilite"><pre><span class="n">Deferred</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">deferred</span> <span class="p">=</span> <span class="n">new</span> <span class="n">Deferred</span><span class="o">&lt;&gt;</span><span class="p">();</span>
<span class="n">new</span> <span class="n">Thread</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">int</span> <span class="n">result</span> <span class="p">=</span> <span class="n">calculateErrorProneSum</span><span class="p">();</span>
<span class="n">deferred</span><span class="p">.</span><span class="n">resolve</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">deferred</span><span class="p">.</span><span class="n">fail</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}).</span><span class="n">start</span><span class="p">();</span>
<span class="n">Promise</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">p</span> <span class="p">=</span> <span class="n">deferred</span><span class="p">.</span><span class="n">getPromise</span><span class="p">();</span>
<span class="p">...</span>
</pre></div>
<h2 id="using-osgi-promises">Using OSGi Promises<a class="headerlink" href="#using-osgi-promises" title="Permanent link">&para;</a></h2>
<p>Once you have a promise, what do you do with it? It's easy to get the value from a promise using the <em>getValue()</em> method,
or you can use the <em>getFailure()</em> method to get the failure cause. Unfortunately both of these methods block until the promise
resolves, and whilst the <em>isDone()</em> method does tell you if the Promise has completed they really aren't the right way to use a
Promise.</p>
<p>Promises work best when you register callbacks and/or transformations. The Promise API has a variety of useful methods for
doing work with the Promise when it resolves. For example we can run a task after the promise completes successfully:</p>
<div class="codehilite"><pre><span class="n">Promise</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">promise</span> <span class="p">=</span> <span class="p">...</span>
<span class="n">promise</span><span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">p</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="n">out</span><span class="p">.</span><span class="n">println</span><span class="p">(</span>&quot;<span class="n">The</span> <span class="n">calculator</span> <span class="n">returned</span> &quot; <span class="o">+</span> <span class="n">p</span><span class="p">.</span><span class="n">getValue</span><span class="p">());</span>
<span class="k">return</span> <span class="n">null</span><span class="p">;</span>
<span class="p">});</span>
</pre></div>
<p>We can also register callbacks to handle failures:</p>
<div class="codehilite"><pre><span class="n">Promise</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">promise</span> <span class="p">=</span> <span class="p">...</span>
<span class="n">promise</span><span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">p</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="n">out</span><span class="p">.</span><span class="n">println</span><span class="p">(</span>&quot;<span class="n">The</span> <span class="n">calculator</span> <span class="n">returned</span> &quot; <span class="o">+</span> <span class="n">p</span><span class="p">.</span><span class="n">getValue</span><span class="p">());</span>
<span class="k">return</span> <span class="n">null</span><span class="p">;</span>
<span class="p">},</span> <span class="n">p</span> <span class="o">-&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">getFailure</span><span class="p">().</span><span class="n">printStackTrace</span><span class="p">());</span>
</pre></div>
<h3 id="chaining-osgi-promises">Chaining OSGi Promises<a class="headerlink" href="#chaining-osgi-promises" title="Permanent link">&para;</a></h3>
<p>In the previous examples our success callback returned <em>null</em> - why? Well the return value from a success callback is always
a promise (null is a shortcut for a promise resolved with null). The promise returned by the callback represents an asynchronous
execution flow in a process known as "chaining". The overall completion of this chain is represented by a third promise, returned
to the caller of the <em>then()</em> method.</p>
<ol>
<li>The caller registers a success callback, and receives a "chained" promise</li>
<li>The original promise completes successfully</li>
<li>The success callback runs and returns a promise representing another piece of asynchronous work</li>
<li>The promise returned by the success callback completes successfully</li>
<li>The "chained" promise completes with the same value as the promise from step 4.</li>
</ol>
<h2 id="other-promise-behaviours">Other Promise behaviours<a class="headerlink" href="#other-promise-behaviours" title="Permanent link">&para;</a></h2>
<p>As well as simple callbacks Promises also provide advanced mapping and recovery features. For example a promise can be
wrapped so that if the original work fails then a new value can be supplied using a recovery function.</p>
<p>The <em>org.osgi.util.promise.Promises</em> utility class also provides useful functions for working with promises. For example helper
methods to wrap an existing value or failure in a Promise, or a way of aggregating a group of promises into a single promise.</p>
<h1 id="the-async-service">The Async service<a class="headerlink" href="#the-async-service" title="Permanent link">&para;</a></h1>
<p>Most OSGi services have a synchronous API. This is usually the easiest way to think about, write, and use services. The main
problem with this is that long running service calls can cause applications to run slowly, and making the calls asynchronous is
both verbose and error-prone.</p>
<p>The Async service is designed to take away the boilerplate code needed to invoke a service asynchronously, and to convert any
synchronous API into an asynchronous API, returning promises instead of values.</p>
<h2 id="using-the-async-service">Using the Async service<a class="headerlink" href="#using-the-async-service" title="Permanent link">&para;</a></h2>
<p>The Async service is available in the service registry and is very easy to use - first we need to mediate the service.
Mediating is a bit like creating a mock object, the mediator records method calls made against it so that they can be
transformed into asynchronous calls. Mediating can apply to a concrete object, or to a ServiceReference. It is better to
use a ServiceReference when one is available, as the Async service can track the availability of the backing service.</p>
<div class="codehilite"><pre><span class="n">Async</span> <span class="n">async</span> <span class="p">=</span> <span class="p">...;</span>
<span class="n">ServiceReference</span><span class="o">&lt;</span><span class="n">MyService</span><span class="o">&gt;</span> <span class="n">ref</span> <span class="p">=</span> <span class="p">...;</span>
<span class="n">MyService</span> <span class="n">mediator</span> <span class="p">=</span> <span class="n">async</span><span class="p">.</span><span class="n">mediate</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">MyService</span><span class="p">.</span><span class="n">class</span><span class="p">);</span>
</pre></div>
<p><em>or</em></p>
<div class="codehilite"><pre><span class="n">Async</span> <span class="n">async</span> <span class="p">=</span> <span class="p">...;</span>
<span class="n">MyService</span> <span class="n">svc</span> <span class="p">=</span> <span class="p">...;</span>
<span class="n">MyService</span> <span class="n">mediator</span> <span class="p">=</span> <span class="n">async</span><span class="p">.</span><span class="n">mediate</span><span class="p">(</span><span class="n">svc</span><span class="p">,</span> <span class="n">MyService</span><span class="p">.</span><span class="n">class</span><span class="p">);</span>
</pre></div>
<p>Once a service has been mediated the mediator should be called just like the real service object, and the return value passed to
the Async service's <em>call()</em> method. This returns a promise representing the asynchronous work.</p>
<div class="codehilite"><pre><span class="n">Promise</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;</span> <span class="n">promise</span> <span class="p">=</span> <span class="n">async</span><span class="p">.</span><span class="n">call</span><span class="p">(</span><span class="n">mediator</span><span class="p">.</span><span class="n">calculateReallyHardSum</span><span class="p">());</span>
</pre></div>
<h3 id="void-methods">Void methods<a class="headerlink" href="#void-methods" title="Permanent link">&para;</a></h3>
<p>Void methods don't have a return value to pass to the async service, and should use the no-args version of call instead.</p>
<div class="codehilite"><pre><span class="nx">mediator</span><span class="p">.</span><span class="nx">longRunningVoidMethod</span><span class="p">()</span>
<span class="nx">Promise</span><span class="cp">&lt;?</span><span class="o">&gt;</span> <span class="nx">promise</span> <span class="o">=</span> <span class="nx">async</span><span class="o">.</span><span class="nx">call</span><span class="p">();</span>
</pre></div>
<h3 id="fire-and-forget-calls">Fire and Forget calls<a class="headerlink" href="#fire-and-forget-calls" title="Permanent link">&para;</a></h3>
<p>Sometimes the user does not care when a piece of work finishes, or what value it returns, or even whether it was successful.
These sorts of calls are called "fire and forget" calls, and are also supported by the async service using the <em>execute()</em> method.</p>
<p>The execute method still returns a promise, however this promise represents whether the fire and forget call successfully started
or not, not whether it has completed.</p>
<h1 id="getting-started">Getting Started<a class="headerlink" href="#getting-started" title="Permanent link">&para;</a></h1>
<p>Releases of the Async implementation can be found in Maven Central <a href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.apache.aries.async%22" title="org.apache.aries.async">in the org.apache.aries.async group</a>. <a href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22org.apache.aries.async%22">This bundle</a> provides a convenient all-in-one download.</p>
<p>The Asynchronous Services source code can be found in the Apache Aries codebase in the <code>async</code> directory: <a href="https://svn.apache.org/repos/asf/aries/trunk/async">https://svn.apache.org/repos/asf/aries/trunk/async</a></p></div>
<!-- Content -->
</td>
</tr>
</table>
</td>
<td id="cell-2-2" colspan="2">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-3-0">&nbsp;</td>
<td id="cell-3-1">&nbsp;</td>
<td id="cell-3-2">
<div id="footer">
<!-- Footer -->
<div id="site-footer">
<a href="http://aries.apache.org/privacy-policy.html";>Privacy
Policy</a>
</div>
<!-- Footer -->
</div>
</td>
<td id="cell-3-3">&nbsp;</td>
<td id="cell-3-4">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-4-0" colspan="2">&nbsp;</td>
<td id="cell-4-1">&nbsp;</td>
<td id="cell-4-2" colspan="2">&nbsp;</td>
</tr>
</table>
</body>
</html>