Mail Archive Home | fractal-commits List | Febuary 2007 Index
| <-- Date Index --> | <-- Thread Index --> |
Date: Sunday, February 11, 2007 @ 17:48:26
Author: pcdavid
Path: /cvsroot/fractal/web
Added: html/tutorials/fscript/example-fractal.png
xml/root/fscript/index.xml xml/root/tutorials/fscript/index.xml
Modified: xml/root/index.xml
Added a subpage for FScript and a corresponding tutorial.
--------------------------------------------+
html/tutorials/fscript/example-fractal.png | <<Binary file>>
xml/root/fscript/index.xml | 51 ++
xml/root/index.xml | 4
xml/root/tutorials/fscript/index.xml | 688 +++++++++++++++++++++++++++
4 files changed, 742 insertions(+), 2 deletions(-)
Index: web/html/tutorials/fscript/example-fractal.png
<<Binary file>>
Index: web/xml/root/fscript/index.xml
diff -u /dev/null web/xml/root/fscript/index.xml:1.1
--- /dev/null Sun Feb 11 17:48:26 2007
+++ web/xml/root/fscript/index.xml Sun Feb 11 17:48:26 2007
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE document SYSTEM '../../../common/dtd/objectweb.dtd'>
+<document>
+ <properties>
+ <author email="fractal@xxxxxxxxxxxxx">Fractal team</author>
+ <title>FPath and FScript</title>
+ <filename>index.xml</filename>
+ <pathtoroot>..</pathtoroot>
+ </properties>
+ <body>
+ <s1 name="FPath and FScript">
+
+ <p><strong>FPath</strong> is a notation inspired
+ by <a href="http://www.w3.org/TR/xpath">XPath</a> which makes it easy
to
+ navigate inside Fractal architectures to discover its strucutre or
find
+ elements (components or interfaces) which match certain criterions.
+ Compared to the direct use of the Fractal PIs, a simple FPath query
can
+ often replace dozens of lines of Java code.</p>
+
+ <p><strong>FScript</strong> is a scripting language dedicated to
Fractal
+ components architectural reconfigurations. It builds upon FPath but
adds
+ the possibility to define reconfiguration scripts to modify the
+ architecture of a Fractal application. Like FPath, FScript is much
more
+ concise the direct API usage. In addition, the FScript interpreter
+ guarantees that the reconfiguration will finish and is atomic: either
it
+ is completely and correctly applied, or not at all (in case of an
+ error).</p>
+
+ <subtitle anchor="download">Download</subtitle>
+
+ <p>There is no released version of FScript yet, but you can get
+ the current version of the code
+ from <a href="http://forge.objectweb.org/cvs/?group_id=22">the
+ ObjectWeb Forge CVS</a>.</p>
+
+ <subtitle anchor="documentation">Documentation</subtitle>
+
+ <p><a href="../tutorials/fscript/index.html">This document</a> presents
+ both FPath and FScript.</p>
+
+ <subtitle>Mailing list</subtitle>
+
+ <p>Questions, comments, ideas, etc. related to FPath and FScript
+ can be posted on
+ the <a href="http://www.objectweb.org/wws/info/fractal">Fractal
mailing
+ list</a>.</p>
+
+ </s1>
+
+ </body>
+</document>
Index: web/xml/root/index.xml
diff -u web/xml/root/index.xml:1.35 web/xml/root/index.xml:1.36
--- web/xml/root/index.xml:1.35 Tue Jan 16 23:08:58 2007
+++ web/xml/root/index.xml Sun Feb 11 17:48:26 2007
@@ -163,7 +163,7 @@
of the Fractal component model.
</li>
<li>
- <strong>FScript</strong>
+ <strong><a href="fscript/index.html">FScript</a></strong>
is the Fractal scripting language.
</li>
<li>
@@ -173,4 +173,4 @@
</ul>
</s1>
</body>
-</document>
\ No newline at end of file
+</document>
Index: web/xml/root/tutorials/fscript/index.xml
diff -u /dev/null web/xml/root/tutorials/fscript/index.xml:1.1
--- /dev/null Sun Feb 11 17:48:26 2007
+++ web/xml/root/tutorials/fscript/index.xml Sun Feb 11 17:48:26 2007
@@ -0,0 +1,688 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE document SYSTEM '../../../../common/dtd/objectweb.dtd'>
+<document>
+ <properties>
+ <author email="fractal@xxxxxxxxxxxxx">Fractal Team</author>
+ <title>FPath and FScript</title>
+ <filename>index.xml</filename>
+ <pathtoroot>../..</pathtoroot>
+ </properties>
+
+ <body>
+ <s1 name="FPath and FScript Tutorial">
+ <ul>
+ <li><strong>Author:</strong> <em>Pierre-Charles David</em>
(EMN/INRIA, LINA)</li>
+ <li><strong>Released:</strong> <em>February 11<sup>th</sup>,
2007</em></li>
+ </ul>
+ </s1>
+
+ <s1 name="Table of Contents">
+ <ol>
+ <li><connect href="index.xml#intro">Introduction</connect></li>
+ <li><connect href="index.xml#fpath">Navigation With The FPath
Notation</connect></li>
+ <ol>
+ <li><connect href="index.xml#fpathmodel">Model</connect></li>
+ <li><connect href="index.xml#fpathprinciple">Principle of
operation</connect></li>
+ <li><connect href="index.xml#fpathexamples">Example
expressions/requests</connect></li>
+ </ol>
+ <li><connect href="index.xml#fscript">FScript
Reconfigurations</connect></li>
+ <ol>
+ <li><connect href="index.xml#guarantees">Safety
guarantees</connect></li>
+ </ol>
+ <li><connect href="index.xml#usage">Usage</connect></li>
+ <ol>
+ <li><connect href="index.xml#api">Java API</connect></li>
+ <li><connect href="index.xml#console">Interactive
console</connect></li>
+ </ol>
+ <li><connect href="index.xml#conclusion">Conclusion and Future
Work</connect></li>
+ </ol>
+ </s1>
+
+ <s1 name="1. Introduction" anchor="intro">
+ <p>One of the main features of the Fractal component model
+ is that it is fully dynamic and reflexive: it is possible both
+ to <em>discover</em> the structure of a Fractal application
+ (introspection) and to <em>modify</em> it (intercession) at
+ runtime. This makes it possible to build, for example,
+ administration tools like Fractal Explorer with which it is
+ easy to navigate inside a running application and modify it
+ interactively. It is also possible to program dynamic
+ reconfigurations, even unanticipated ones, to be executed in a
+ running application. This is important in order to evolve
+ applications without stopping and redeploying them (for
+ example to update a component or subsystem) and to build
+ self-adaptive and autonomic systems which must take
+ reconfiguration decisions -- and apply them -- dynamically and
+ automatically (i.e. without human intervention).</p>
+
+ <p>Such dynamic discovery and reconfigurations can be programmed
+ in the same language than the application itself, for example
+ Java, using the standard Fractal APIs. However, such an
+ approach has several drawbacks:</p>
+
+ <ul>
+ <li>The Fractal APIs are designed to be minimalist and
+ orthogonal, which is good for tool writers but can be
+ cumbersome and lead to verbose code when used to program
+ specific reconfigurations.</li>
+
+ <li>Fractal introduces new concepts like interfaces and
+ bindings, which are not integrated at the host language
+ level, especially in the syntax. This can lead to confusion,
+ for example in Java where two related but distinct concepts
+ of interfaces coexist (Java interfaces and component
+ interfaces): Fractal interfaces are represented by Java
+ objects which implement both a language-level interface and
+ the <code>Interface</code> interface...</li>
+
+ <li>Although Java is a relatively dynamic language, which
+ supports dynamic code loading, it is not lightweight and
+ dynamic enough to support dynamic definition and execution
+ of unanticipated reconfigurations in a simple way. To apply
+ an unanticipated Fractal reconfiguration to a running
+ application one would need to: (i) write the actual
+ reconfiguration using the Fractal API, with the issues
+ stated above, (ii) compile this code, which requires a JDK
+ and access to the running application class files for type
+ checking, (iii) deploy the class files on the host system
+ and load it in the JVM running the target application, and
+ (iv) finally execute the code.</li>
+
+ <li>Finally, Java being a general purpose language, it is
+ not possible to offer guarantees when executing a Fractal
+ reconfiguration programmed in Java. For example, nothing
+ prevents the reconfiguration code to access and corrupt
+ (intentionally or not) private data structures, to call
+ dangerous method (<code>System.exit()</code>), or simply to
+ loop forever.</li>
+ </ul>
+
+ <p>In order to overcome these limitations while still retaining
+ Fractal's advantages, we have designed and implemented a new
+ language, called FScript, to navigate inside Fractal
+ architectures and dynamically reconfigure them. FScript can be
+ though of as the dual of the standard Fractal ADL: while the
+ ADL (Architecture Description Language) uses
+ a <em>declarative</em> approach to specify
+ the <em>initial</em> configuration of an application, FScript
+ is an <em>imperative</em> language and is used
+ to <em>incrementally reconfigure</em> a running
+ application.</p>
+
+ <p>To do this, FScript provides a special notation called FPath
+ to navigate intuitively inside an architecture and select
+ parts of it (<connect href="index.xml#fpath">Section
+ 2</connect>). These elements can then be acted upon to
+ reconfigure the architecture using primitive Fractal
+ operations or user-defined reconfigurations scripts
+ (<connect href="index.xml#fscript">Section 3</connect>).
+ Beyond its direct syntactic support for Fractal concepts, the
+ main feature of FScript is that it provides guarantees on the
+ consistency of the reconfigurations
+ (<connect href="index.xml#guarantees">Section 3.1</connect>)
+ by considering these as transactions. FScript has been
+ implemented as a simple interpreter which can be easily
+ embedded in a Fractal application (in Java), or used
+ interactively through a text console
+ (<connect href="index.xml#usage">Section 4</connect>).</p>
+ </s1>
+
+ <s1 name="2. Navigation With The FPath Notation" anchor="fpath">
+
+ <p>FPath is a special notation used inside the FScript language
+ to <em>navigate</em> inside Fractal architectures
+ and <em>select</em> elements in it according to some
+ predicate. Its syntax and execution model are inspired by
+ the <a href="http://www.w3.org/TR/xpath">XPath language</a>
+ which solves the same problem on XML documents (although FPath
+ does not use XML at all).</p>
+
+ <s2 name="2.1. Model" anchor="fpathmodel">
+
+ <p>FPath sees a given Fractal architecture as an oriented graph with
labelled arcs.
+ Different kinds of nodes represent all the architectural
+ elements we chose to reify:</p>
+
+ <ul>
+ <li>the <em>components</em> themselves (not reified as such
+ in Fractal, but only through the <code>component</code>
+ interface);</li>
+
+ <li>component <em>interfaces</em> (both external and internal);</li>
+
+ <li>configuration <em>attributes</em>, corresponding to
+ getter/setter methods
+ on <code>attribute-controller</code>s;</li>
+
+ <li>and finally <em>methods</em> on the interfaces.</li>
+ </ul>
+
+ <p>These nodes are connected by labelled arcs, which denote
+ the kind of relation between them. For example, an arc
+ labelled <code>interface</code> goes from a given component
+ node to each interface node representing the component's
+ interfaces. In the same way, if composite <code>C1</code>
+ contains <code>C2</code> as a sub-component, the
+ corresponding nodes <code>N1</code> and <code>N2</code> will
+ be connected by two arcs: one labelled <code>child</code>
+ from <code>N1</code> to <code>N2</code>, and one
+ labelled <code>parent</code> from <code>N2</code>
+ to <code>N1</code>.</p>
+
+ <p>The following types of arcs, called axes are defined in
+ FPath:</p>
+
+ <ul>
+ <li><code>component</code>: from any kind of node to the
+ component owning this node;</li>
+
+ <li><code>attribute</code>: from a component node to all its
+ configuration attributes;</li>
+
+ <li><code>interface</code>: from a component node to all its
+ interfaces, and from a method node to the interface of
+ which it is part;</li>
+
+ <li><code>method</code>: from an interface to all its
+ methods;</li>
+
+ <li><code>binding</code>: from an client interface node to
+ the server interface it is bound to, if any;</li>
+
+ <li><code>child</code> (resp. <code>parent</code>): from a
+ component to its direct children (resp. parents);</li>
+
+ <li><code>sibling</code>: from a component to all the other
+ components which have at least one direct super-component
+ in common with it;</li>
+
+ <li><code>descendant</code> (resp. <code>ancestor</code>):
+ from a component to all its direct and indirect children
+ (resp. parents). <code>descendant</code>
+ (resp. <code>ancestor</code>) is thus the transitive
+ closure of <code>child</code>
+ (resp. <code>parent</code>).</li>
+ </ul>
+
+ </s2>
+
+ <s2 name="2.2. Principle of operation" anchor="fpathprinciple">
+ <p>Given this representation, FPath expressions
+ denote <em>relative paths</em> starting from an initial (set of)
+ node(s) in the graph. Such a path is made of a series of steps, each
+ made of up to three elements: <code>axis::test[predicate]</code>
(the
+ predicate is optional). On each step, an initial set of nodes is
+ converted to a new set by following all the arcs with a label
+ corresponding to the axis, then filtering the result using
+ the <em>test</em> (on the node names) and optional
<em>predicates</em>
+ (boolean expressions applied to each candidate). For a multi-step
+ path, this algorithm is repeated with the result of the previous
step
+ as the current node-set of the next.</p>
+
+ <p>For example, the FPath expression
+ <code>sibling::*/interface::*[provided(.)][not(bound(.))]</code>
+ is made of two steps. The first one uses
+ the <code>sibling</code> axis, an "empty"
+ test <code>*</code> (which is always true) and has no
+ predicate. The second step uses the <code>interface</code>
+ axis, no test either, and two predicates which are combined.
+ Inside the predicates, the dot "<code>.</code>" represents
+ the current node on which the predicate is evaluated.
+ Evaluating the complete expression starting from an initial
+ component node will:</p>
+ <ol>
+ <li>select all its sibling components, however they are
+ named;</li>
+ <li>select all the external interfaces of these
+ siblings;</li>
+ <li>filter this set of interfaces to return only server
+ interfaces (<code>provided()</code>) which are not already
+ bound.</li>
+ </ol>
+
+ <p>The expressions used as predicates can be any FPath
+ expression, which includes not only paths but also standard
+ arithmetic operations, comparisons, function calls, litteral
+ strings and numbers and finally variable references
+ (<code>$varName</code>). When a path expression is used as a
+ predicate, it is considered true if and only if it returns a
+ non-empty set of nodes. For example, to find all the
+ components in a application which provide configuration
+ attributes, one could use the following expression on the
+ application's root
+ component: <code>descendant-or-self::*[attribute::*]</code>.
+ This initially selects all the components contained in the
+ root, recursively, and then filters this set to retain only
+ those from which the step <code>attribute::*</code> returns
+ a non-empty set, i.e. the nodes which have configuration
+ attributes. Note that this expression is different
+ from <code>descendant-or-self::*/attribute::*</code>, which
+ returns the configuration attributes themselves, not the
+ components which provide them.</p>
+ </s2>
+
+ <s2 name="2.3. Example expressions/requests" anchor="fpathexamples">
+
+ <p>These example expressions are described in the context of
+ the following example application:</p>
+
+ <p><img src="example-fractal.png" alt="Example Fracal architecture"
+ border="0" width="569" height="369"/></p>
+
+ <ul>
+ <li><em>Simple navigation</em>:
+
+
<source>$root/child::client/interface::server/binding::*/parent::*</source>
+
+ <p>From the <code>root</code> component, selects its direct child
+ named <code>client</code>, then follows the binding of its
+ interface named <code>server</code>, resulting
+ the <code>service</code> interface. The final step finds the
+ parent(s) of this node. The <code>service</code> node is an
+ interface node, and thus has no parent; however, it is owned by
+ a <code>component</code> node which can have parents. Normally,
+ one should have to add a <code>component::*</code> step
+ before <code>parent::*</code>, but FPath can do it automatically
+ for interface and attribute nodes. The final result is a
singleton
+ which contains the initial <code>root</code> component node.</p>
+ </li>
+
+ <li><em>Does the current component have required interfaces which
are
+ not yet bound?</em>
+
+ <source>count($c/interface::*[required(.) and not(bound(.))]) >
0</source>
+
+ <p>Inside predicates, the dot (<code>.</code>) represents the
+ current node to which the test is applied.</p>
+ </li>
+
+ <li><em>Given an interface to connect (for example returned
+ from the previous request), what are the possible
candidates?</em>
+
+ <source>$itf/sibling::*/interface::*[provided(.)][subtype(.,
$itf)]</source>
+
+ <p>The <code>$itf</code> variable represents the interface to
connect.</p>
+ </li>
+
+ <li><em>Which components are shared?</em>
+
+ <source>$root/descendant-or-self::*[count(parent::*) > 1]</source>
+
+ <p>Finds all the components in the system which have more than one
+ parent. The axis <code>descendant-or-self</code> is a variant
+ of <code>descendant</code> which also include the initial nodes
in
+ the result. Suche variants also exist
+ for <code>child</code>, <code>parent</code>,
<code>ancestor</code>
+ and <code>sibling</code>.</p>
+ </li>
+
+ <li><em>After navigation from the root, find the <code>header</code>
+ configuration attribute of the server component.</em>
+
+
<source>$root/child::client/interface::s/binding::*/attribute::header</source>
+
+ <p>For comparison, here is the equivalent Java code using the
+ standard Fractal API:</p>
+
+ <source><![CDATA[
+try {
+ ContentController cc = Fractal.getContentController(root);
+ Object[] children = cc.getFcSubComponents();
+ for (int i = 0; i < children.length; i++) {
+ Component kid = (Component) children[i];
+ String name = null;
+ try {
+ NameController nc = Fractal.getNameController(kid);
+ name = nc.getFcName();
+ } catch (NoSuchInterfaceException nsie) {
+ name = "";
+ }
+ if (name.equals("client")) {
+ try {
+ BindingController bc = Fractal.getBindingController(kid);
+ Interface itf = (Interface) bc.lookupFc("s");
+ if (itf != null) {
+ Component other = itf.getFcItfOwner();
+ AttributeController ac= Fractal.getAttributeController(other);
+ Class klass = ac.getClass();
+ try {
+ Method meth = null;
+ try {
+ meth = klass.getMethod("getHeader", null);
+ } catch (NoSuchMethodException nime) {
+ meth = klass.getMethod("isHeader", null);
+ }
+ if (meth != null) {
+ try {
+ Object value = meth.invoke(ac, null);
+ System.out.println(value);
+ } catch (Exception e) { /* ignore */
+ }
+ } catch (Exception e) { /* ignore */ }
+ }
+ } catch (NoSuchInterfaceException nsie) { /* ignore */ }
+ }
+ }
+} catch (NoSuchInterfaceException nsie) {
+ // ignore
+}
+]]></source>
+ </li>
+ </ul>
+ </s2>
+ </s1>
+
+ <s1 name="3. FScript Reconfigurations" anchor="fscript">
+
+ <p>The preceding section described the FPath notation which is used to
navigate
+ inside a Fractal architecture and select parts of it, but can not
modify
+ the architecture. The complete FScript language, of which FPath is
just
+ a part, enables the definition of <em>reconfiguration actions</em> to
+ apply to a running application. FScript is a simple
+ imperative/procedural language whose main features are:</p>
+ <ul>
+ <li>direct syntaxic support for naviagation in Fractal architectures
+ thanks to FPath;</li>
+ <li>safety guarantees on the application of the reconfigurations;</li>
+ <li>a very dynamic implementation which does not impose a compilation
+ phase and can be easily embedded into existing applications, where
+ reconfiguration scripts can then be dynamically loaded and
+ executed.</li>
+ </ul>
+
+ <p>In this section, we present the syntax and semantics of the rest of
the
+ language, beyond FPath.</p>
+
+ <p>Here is a simple example of the definition of an FScript
reconfiguration action
+ which illustrates almost all of FScript constructs. It automatically
+ connects a component's required interfaces by discovering the
compatible
+ server interfaces on sibling components.</p>
+
+ <source><![CDATA[
+action auto-bind(comp) = {
+ // Selects the interfaces to connect
+ clients := $comp/interface::*[required(.)][not(bound(.))];
+ foreach itf in $clients do {
+ // Search for candidates compatible interfaces
+ candidates := $comp/sibling::*/interface::*[compatible?($itf, .)];
+ if (not(empty?($candidates))) {
+ // Connect one of these candidates
+ bind($itf, one-of($candidates));
+ }
+ }
+ return empty?($comp/interface::*[required(.)][not(bound(.))]);
+}
+]]></source>
+
+ <p>This defines a new reconfiguration action named
<code>auto-bind</code>,
+ which takes one parameter, named <code>comp</code>. The body of the
+ action is defined inside braces, and consists in a sequence of simple
+ statements (assignements and procedure calls) ended with semicolons
and
+ control structures (iteration and conditionals). FScript also supports
+ comments, using C/C++ syntax.</p>
+
+ <p>Given a component <code>comp</code> as parameter, this action first
uses an
+ FPath expression to find all its client interfaces which are not yet
+ bound, and stores the result in variable <code>clients</code>. The
+ action the iterates over this set of client interfaces using
+ the <code>itf</code> iteration variables. On each iteration, the
action
+ searches for compatible interfaces on the siblings of
<code>com</code>,
+ again using an FPath expression. This set of candidates is stored in
+ variable <code>candidates</code>. Finally, the action tests whether
this
+ set is empty, and if not, uses the primitive action
<code>bind()</code>
+ (which corresponds to Fractal's
<code>BindingController#bindFc()</code>
+ method) to connect the client interface <code>itf</code> to one of the
+ candidates. Finally, it returns a boolean indicating whether all
client
+ interfaces have been bound.</p>
+
+ <p>FScript distinguishes two kinds of procedures: functions and
actions.
+ Functions are guaranteed to be side-effect free, and can only
introspect
+ an architecture, not modify it. They can be used safely inside FPath
+ requests, for example in the predicates. Functions are defined like
+ actions, expect that they use the <code>function</code> keyword
instead
+ of <code>action</code>, and can only invoke other functions, not
actions
+ (be they primitive or user defined). FScript provides a standard
library
+ of primitive functions and actions which gives the user access to all
+ the information available from the Fractal API, and all the standard
+ reconfigurations.</p>
+
+ <p>The complete list of primitive actions is the following:</p>
+ <ul>
+ <li><code>new(tmplName)</code> instanciates and returns a new
component
+ using the Fractal ADL. The name passed as a parameter is used as is
by
+ the ADL's <code>Factory</code>.</li>
+
+ <li><code>add(composite, subcomponent)</code>
+ and <code>remove(composite, subcomponent)</code> are used to add and
+ remove a sub-component from a composite. They correspond
+ to <code>ContentController</code>'s <code>addFcSubComponent()</code>
+ and <code>removeFcSubComponent()</code>.</li>
+
+ <li><code>bind(clientItf, serverItf)</code>
+ and <code>unbind(clientItf)</code> are used to bind two compatible
+ interfaces together and to unbind a client interface. They
correspond
+ to <code>BindingController</code>'s <code>bindFc()</code>
+ and <code>unbindFc()</code>.</li>
+
+ <li><code>start(component)</code> and <code>stop(component)</code> are
+ used to start and stop a component. They correspond
+ to <code>LifeCycleController</code>'s <code>startFc()</code>
+ and <code>stopFc()</code>.</li>
+
+ <li><code>set-name(component, name)</code> changes the name of a
+ component, using its <code>NameController</code>.</li>
+
+ <li><code>set-value(attribute, value)</code> changes the value of a
+ configuration attribute accessible through
+ its <code>AttributeController</code>.</li>
+ </ul>
+
+ <p>As Fractal is designed to be extensible, new controllers -- and
hence
+ new reconfigurations operations -- can be added to the model. FScript
is
+ designed and implemented so that it is easy to add the corresponding
+ FScript primitives.</p>
+
+ <p>Variables in FScript are not typed (values are). They are created
+ either explicitely on their first assignment (<code>varName :=
+ expression;</code>) or implicitely when entering inside the body of
a
+ procedure, where parameters behave like local variables. Variable
+ reference is done by preceding the name of the variable with a dollar
+ sign (<code>varName</code>). Variables are lexically scoped, but only
+ procedure bodies introduce a new scope, not conditionals and
+ iterations.</p>
+
+ <p>The control structures available in FScript are voluntarily limited
so
+ that we can guarantee the termination of all reconfigurations. They
+ are:</p>
+
+ <ul>
+ <li>Conditionals use the classical <code>if/then/else</code>
structure.
+ The condition must be a side-effect free expression (i.e. an FPath
+ expression or function call but not an action call) and is evaluated
+ for its boolean value.</li>
+ <li>Bounded iteration have the following syntax:
+ <source>foreach i in expression do {
+ body
+}</source>
+
+ Where <code>i</code> is the name of the iteration variable to use
+ (without the dollar sign), <code>expression</code> is an FPath
+ expression which must return a set of nodes, and <code>body</code>
is
+ a sequence of statements. <code>body</code> is executed for each
+ element of the set of nodes returned by <code>expression</code> in
+ turn, with <code>i</code> bound to the current element.</li>
+
+ <li>A procedure can return a value immediatly and stop its execution
by
+ using <code>return expression;</code>.</li>
+ </ul>
+
+ <s2 name="3.1. Safety guarantees" anchor="guarantees">
+
+ <p>FScript's design and implementation guarantee the consistency of
+ reconfigurations. Because these reconfigurations are applied to
+ running applications, we must guarantee that they will not break the
+ target system. To this end, we have chosen a set of consistency
+ criterion, in particular <em>transactional integrity</em>
(atomicity,
+ consistency of the final state, isolation) and <em>termination</em>
of
+ the reconfigurations. The validation of these criteria is guaranteed
+ in part by the language's structure itself, whose expressive power
has
+ been limited, and in part by the implementation. More precisely:</p>
+
+ <ul>
+ <li>The definition of (directly or indirectly) recursive actions is
+ forbidden, and the only control structure available for iteration,
+ a <code>for each</code> loop, iterates on the result of an FPath
+ expression, which always returns a finite set of nodes. These
+ constraints guarantee actions' <em>termination</em>, although they
+ do not provide a time bound.</li>
+
+ <li>During the execution of a reconfiguration, the language
+ interpreter keeps a complete journal of all the primitive actions
+ performed, together with enough information to revert them. As
soon
+ as an error occurs, the interpreters uses this journal to
roll-back
+ the current reconfiguration and return to the initial state. Given
+ that all the primitive Fractal reconfigurations are themselves
+ atomic and reversible, this guarantees the <em>atomicity</em> of
+ FScript reconfigurations.</li>
+
+ <li>At the end of a reconfiguration, the interpreter checks that the
+ current configuration is consistent, i.e. that all the required
+ client interfaces are correctly bound to a corresponding server
+ interfaces and that all the components which have been temporarily
+ stopped during the reconfiguration can safely be restarted. If
this
+ is not the case, the interpreters cancels the reconfiguration and
+ rolls back to the initial state, thus ensuring the consistency of
+ the application.</li>
+
+ <li>Finally, the <em>isolation</em> of reconfigurations is currently
+ guaranteed by globally serializing them. This works, but is highly
+ sub-optimal and may be enhanced in future works.</li>
+ </ul>
+
+ </s2>
+ </s1>
+
+ <s1 name="4. Usage" anchor="usage">
+
+ <p>FScript is currently implemented in Java as a simple interpreter.
Care
+ has been taken to make it easy to embed in existing Java applications,
+ with only one external dependency outside of Fractal and Fractal ADL
+ (namely, the ANTLR parsing tool).</p>
+
+ <s2 name="4.1. Java API" anchor="api">
+
+ <p>Once <code>fscript.jar</code> and <code>antlr.jar</code> are
+ available, one can use FScript to query or reconfigure an
application
+ in this way:</p>
+
+ <ol>
+ <li>First, create an interpreter:
+ <source>FScriptInterpreter fscript = new
FScriptInterpreter();</source>
+ </li>
+
+ <li>Optionally load custom functions and actions definitions stored
in
+ external files (this can be done at any time):
+ <source>fscript.loadDefinitions(new
FileReader("mydefinitions.script"));</source>
+ </li>
+
+ <li>Evaluate an FPath expression to query a running Fractal
application. This
+ requires setting up the variables used in the expression,
especially
+ node variables.
+
+ <source>NodeFactory nf = fscript.getNodeFactory();
+Map vars = new HashMap();
+vars.put("root", nf.createComponentNode(aComponent));
+Object result = fscript.evaluate("$root/descendant::*[attribute::size]",
vars);
+for (n : (FractalNode[]) result) {
+ org.objectweb.fractal.api.Component c = n.getComponent();
+ // do something with c
+}</source>
+ </li>
+
+ <li>Execute FScript reconfigurations:
+ <source>result = fscript.execute("my-reconfiguration($root);",
vars);</source>
+ </li>
+ </ol>
+ </s2>
+
+ <s2 name="4.2. Interactive console" anchor="console">
+
+ <p>To enable interactive experimentation, FScript also provides a
simple,
+ text-based console. This console provides a prompt where FPath
+ requests and FScript statements can be entered and executed
+ immediatly. The console also offers a few special commands (starting
+ with <code>!</code>) to load an external file containing custom
+ functions and actions definitions and to launch a component through
+ a <code>Runnable</code> interface. Here is the transcript of a
sample
+ session in which we instanciate the Comanche HTTP server, launch it
+ and reconfigure it dynamically using custom actions loaded
dynamically
+ (lines starting with <code>#</code> are comments and not part of the
+ session):</p>
+
+ <source><![CDATA[
+# Instanciate Comanche from its ADL definition
+FScript> c := new("comanche.Comanche");
+
+# Start the component. This maps to LifecycleController.startFc()
+# and only activates the component. It does not start the server.
+FScript> start($c);
+
+# Actually launches (in a separate thread) the server through the
+# "r" interface (of type Runnable) of the $c component.
+FScript> !run r $c
+
+# Load custom actions to manage a cache component
+FScript> !load cache.fscript
+
+# Enables the cache on an internal component using a custom
+# action. The server does not need to be stopped.
+FScript> h := $c/descendant::rh;
+FScript> enable-cache($h);
+
+# Get the newly added cache component
+FScript> cache := $h/child::cfh;
+
+# Lookup its current maximum size
+FScript> $cache/attribute::maximumSize
+0
+
+# Change this attribute
+FScript> set-value($cache/attribute::maximumSize, 42*1024);
+]]></source>
+
+ </s2>
+ </s1>
+
+ <s1 name="5. Conclusion and Future Work" anchor="conclusion">
+
+ <p>In this paper we have presented FScript, a Domain-Specific Language
+ used to program structural reconfigurations of Fractal architectures.
+ Compared to the use of the standard Fractal APIs in a general purpose
+ language, FScript offers better syntactic support for navigation, more
+ dynamicity, and guarantees on the consistency of the
+ reconfigurations.</p>
+
+ <p>FScript introduces a new notation, called FPath, which is designed
to
+ express queries on Fractal architectures, navigating inside them and
+ selecting elements according to predicates. FPath is embedded inside
the
+ FScript language, but can also be used as a standalone query
+ language.</p>
+
+ <p>FScript provides access to all the primitive reconfiguration actions
+ available in Fractal, and enables the user to define custom
+ reconfigurations using a simple procedural language. The power of
+ expression of the language is voluntarily limited so that guarantees
can
+ be offered, especially termination. The interpeter offers some
+ guarantees on the execution of these reconfiguration: termination,
+ atomicity (undoing already applied changes in case of error),
+ consistency (rolling back the whole reconfiguration if the final state
+ is invalid), and isolation (currently using a global lock).</p>
+
+ <p>The current implementation of FScript is focused on simplicity, but
+ planned enhancements include: static checks, including a type sytem,
+ support for distributed reconfiguration and distributed
reconfiguration
+ transactions, and performance improvements (maybe through a compiler
+ producing Java code).</p>
+ </s1>
+ </body>
+</document>
| <-- Date Index --> | <-- Thread Index --> |
Powered by MHonArc.
Copyright © 2006-2007, OW2 Consortium | contact | webmaster.