OW2 Consortium
Search OW2 Mail Archive: 

Advanced Search - Powered by Google


Mail Archive Home | fractal-commits List | May 2008 Index

<--  Date Index  --> <--  Thread Index  -->

[fractal-commits] [7807] sandbox/debrouxl/comanche/src/site/apt/index.apt: Cecilia Comanche example: third and last chunk of the conversion from LyX to APT.


Title: [7807] sandbox/debrouxl/comanche/src/site/apt/index.apt: Cecilia Comanche example: third and last chunk of the conversion from LyX to APT.
Revision
7807
Author
debrouxl
Date
2008-05-28 13:49:49 +0200 (Wed, 28 May 2008)

Log Message

Cecilia Comanche example: third and last chunk of the conversion from LyX to APT.

Modified Paths

Diff

Modified: sandbox/debrouxl/comanche/src/site/apt/index.apt (7806 => 7807)


--- sandbox/debrouxl/comanche/src/site/apt/index.apt	2008-05-28 11:24:49 UTC (rev 7806)
+++ sandbox/debrouxl/comanche/src/site/apt/index.apt	2008-05-28 11:49:49 UTC (rev 7807)
@@ -300,12 +300,133 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Implementation
 
+  This section explains how to program Fractal component based applications, by
+  using the Comanche example. It also introduces and motivates the concepts and
+  APIs of Fractal that are used.
+
 * Choosing the components' granularity
 
+  As explained in section {{{#Design}Design}}, component oriented design is
+  quite independent from component oriented implementation. In particular, at
+  programming time, it is possible to merge several or even all the design
+  time components into a single, monolithic piece of code, if desired.\
+  For example, in the case of Comanche, one may choose to implement all the
+  design time components into a single class, as shown in section
+  {{{#Design}Design}}.\
+  One may also choose to implement each component in its own class, or to
+  implement some components in their own class, and to merge some other
+  components (such as the request dispatcher and its associated request
+  handlers) into a single class. 
+
+  Using one runtime component per design time component gives maximum
+  flexibility and extensibility, but can be less efficient that merging several
+  design time components into a single runtime component. When in doubt, <the
+  first solution should be preferred>: optimizations can be done later on, if
+  needed.\
+  In the case of Comanche, we will therefore use one runtime component per
+  design time component.
+
 * Implementing the component interfaces
 
+  Before implementing the component themselves, the first step is to implement
+  their <interfaces>. Indeed the Fractal component model requires a strict
+  separation between interfaces and implementation for all components (see
+  section {{{#Introduction}Introduction}}).\
+  This design pattern is indeed useful to easily replace one component
+  implementation with another. It also offers the possibility to add
+  interposition objects between a client and a component implementation, in
+  order to transparently manage some non functional concerns of the component
+  (as in the Enterprise Java Beans model).\
+  The only drawback of this design pattern is that it is a little less
+  efficient than a solution without interfaces. This is why it may sometimes
+  be needed to merge several design time components into a single Fractal
+  component.
+
+  The component interfaces can be implemented easily, since most, if not all,
+  of the work has been done during the definition of the component contracts.
+  In the case of Comanche, three interfaces must be implemented. They are
+  given below (see Appendix Comanche source code for the most importants bits
+  of the source code of Comanche):
+
++------------------------------------------------------------------------------+
+interface RequestHandler { int handleRequest (any r); }
+
+interface Scheduler { void schedule(any task); }
+
+interface Logger { void log(string msg); }
++------------------------------------------------------------------------------+
+
+  Here, anonymous type any was used, but non-component types (such as
+  <<<struct>>>s) can be used in interface method parameters. <This is not
+  recommended>. It is indeed better to use interfaces, even for data structures
+  that are not represented as components: these data structures can then be
+  implemented in various ways (including as components), without needing to
+  change the interfaces that refer to them.\
+  Note also that it would have been better to introduce a request factory
+  component (this was not done for simplification purposes; see the
+  {{{../cloneable/index.html}Cecilia Cloneable example}} for more information
+  on how to do that).
+
 * Implementing the components
 
+  Now that the component interfaces have been implemented, we can implement the
+  components themselves. The components that do not have any dependencies to
+  other components can be programmed like ordinary C ``modules''.
+  For example, the logger component can be implemented as follows:
+
++------------------------------------------------------------------------------+
+#include <stdio.h>
+
+DECLARE_DATA { } ;
+#include <cecilia.h>
+
+void METHOD(l, log) (void *_this, char * msg) {
+    fprintf(stdout,"Basic logger: log \"%s\"\n",msg);
+}
++------------------------------------------------------------------------------+
+
+  In component oriented programming, and in Fractal in particular, the
+  components that have dependencies to other components must be programmed in a
+  specific way. In Cecilia, this is done using the thinkMC ``language'' (C
+  macros such as <<<METHOD>>>, <<<REQUIRED>>> and <<<CALL>>>).\
+  The Cecilia toolchain generates code to glue the components together. This
+  code glue is compiled and linked with your application, and it has support
+  for one of the goals of Fractal, dynamic reconfigurations.
+  
+  In fact, in Fractal, a component with dependencies (or <bindings>) to other
+  components must implement the <<<BindingController>>> interface, defined in
+  the Fractal specification. This interface defines four generic methods
+  <<<listFc>>>, <<<lookupFc>>>, <<<bindFc>>> and <<<unbindFc>>> to manage
+  component bindings.
+
+  The <<<listFc>>> method returns the names of the dependencies of the
+  component, and the <<<lookupFc>>>, <<<bindFc>>> and <<<unbindFc>>> methods
+  are used to read, set and unset the corresponding bindings (the <<<s>>> and
+  <<<rh>>> strings do not have to be equal to the names of the corresponding
+  fields).\
+  This enables good distinction between the <controller> and <content> part of
+  Fractal components (see section {{{#Introduction}Introduction}}): the
+  controller part corresponds to the <<<BindingController>>> interface, and the
+  content part to the <<<boot.api.Main>>> interface (in the logger and scheduler
+  components, the controller part was empty).
+
+  The <<<listFc>>>, <<<lookupFc>>>, <<<bindFc>>> and <<<unbindFc>>> methods are
+  implicitely implemented by the code glue generated by the Cecilia toolchain,
+  if the <cardinality> of the bindings is <singleton> (a single server interface
+  is bound to a client interface). If the <cardinality> is <collection>, you
+  (currently) have to implement the <<<BindingController>>> methods in your
+  source code. The <<<RequestDispatcher>>> component does it.
+
+  In order to do that, you have to know that each binding must have a name of
+  the form <prefix><<postfix>> where <prefix> is common to all the bindings of
+  the collection, and where <<postfix>> is arbitrary, but distinct for each
+  binding.\
+  Have a look at the implementation of the <<<RequestDispatcher>>> component,
+  which contains a partial implementation of the collection binding.
+  Once again, this partial implementation was done for simplification purposes,
+  since <<<Map>>>s (Java) / <<<hashes>>> (Perl and most scripting languages) are
+  not part of the standard C language.
+  
 * Summary
 
   Components must be implemented with an appropriate granularity, resulting from
@@ -318,10 +439,109 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Configuration
 
+  This section presents the method to assemble and deploy Fractal components,
+  always by using the Comanche example. It also introduces and motivates the
+  Fractal tools that are used.
+
 * ADL based configuration
 
+  Configuration and deployment <could> be done using a program that instantiates
+  components, but this method has several drawbacks:
+  
+  * it's not that trivial to program;
+  
+  * it's error prone: it's easy to forget a binding or to create a wrong
+    binding.
+
+  * the component architecture is not directly visible (the component's
+    hierarchy description, in particular, is completely lost);
+  
+  * most importantly, <this method mixes two separate concerns, namely
+    architecture description and deployment>. It is impossible to deploy a
+    given component architecture in several ways, without rewriting the
+    configuration/deployment program).
+
+  []
+  
+  In order to solve these problems, a solution is to use an Architecture
+  Description Language (ADL). As its name implies, an ADL definition describes a
+  component architecture, and only that, i.e. its does not describe the
+  instantiation method. This solves the most important drawback of the previous
+  configuration method.\
+  An ADL is also generally strongly typed, which allows the ADL parser to
+  perform verifications about the declared component architecture. Using an ADL
+  is therefore less error prone and more flexible than using the programmatic
+  approach.
+  
+  Cecilia ADL is a possible, XML based ADL that can be used to describe Fractal
+  component configurations. Other ADLs can be created if needed (indeed these
+  ADLs are not part of the Fractal component model itself: they are just tools
+  based on this model).\
+  Cecilia ADL is strongly typed. The first step to define a component
+  architecture is therefore to define the types of the components. Each
+  component type must specify what components of this type provide to, and
+  require from other components. For example, the type of the file and error
+  handler components (but also of the request handler and backend components),
+  in Comanche, can be defined as follows (these components provide a
+  <<<RequestHandler>>> interface, and do not have dependencies):
+
+%{snippet|id=Content|url=""
+
+  Components with dependencies are declared in a similar way. For example, the
+  type of the request dispatcher component, in Comanche, can be defined as
+  follows:
+
+%{snippet|id=Content|url=""
+
+  Note that this type is declared to <extend> the previous handler type: this
+  means that the provided and required interface types declared in the handler
+  type are inherited by the dispatcher type. Note also the optional
+  <cardinality> attribute in the interface type definition: it means that
+  components of this type can have a variable number of bindings (as mentioned
+  above).
+
+  After the component types have been defined, the components themselves can be
+  defined. Here Cecilia ADL distinguishes between components that do not expose
+  their content, called <<primitive components>>, and components that do expose
+  it, called <<composite components>>.
+  
+  A primitive component is defined by specifying its component type and the C
+  ``module'' that implements it. For example, the file handler component can
+  be defined as follows:
+
+%{snippet|id=Content|url=""
+
+  A composite component is defined by specifying its sub-components, and the
+  bindings between these sub-components. For example, the Comanche composite
+  component, which represents the whole application, and which contains the
+  Frontend and Backend components, can be defined as follows:
+
+%{snippet|id=Content|url=""
+
+  This definition says that the Comanche component provides a <<<Runnable>>>
+  interface (to start the application), that it contains two sub components
+  named <<<fe>>> and <<<be>>>, that the <<<Runnable>>> interface provided by
+  Comanche (<<<this.r>>>) is provided by the <<<Runnable>>> interface of its
+  frontend sub-component (<<<fe.r>>>), and that the request handler required
+  by the frontend sub-component (<<<fe.rh>>>) is provided by the backend
+  component (<<<be.rh>>>).
+
+  Once the application's architecture has been defined, it can be compiled,
+  which gives a C ``module'', in source code. The Cecilia ADL parser performs
+  preliminary verifications to check the architecture and, in particular,
+  to check that there is no missing or invalid binding.
+
+  If one wants to change the implementation of one or more of the components
+  used in the program (e.g. use a multi-threaded scheduler instead of a
+  sequential, synchronous one), modifying a few characters in an ADL file
+  is all that's necessary.
+
 * Summary
 
+  Components can be configured and deployed in two different ways. The
+  programmatic approach mixes different concerns, and is not that trivial to
+  implement in C. The ADL-based approach correctly separates these concerns.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Conclusion
 
@@ -377,7 +597,8 @@
   implementation-specific files (semaphores, wrappers for several POSIX/*nix
   functions).
   
-  Notice the <<METHOD>>, <<CALL>> and <<DECLARE_DATA>> syntactic sugar.
+  Notice the <<METHOD>>, <<CALL>>, <<REQUIRED>> and <<DECLARE_DATA>> syntactic
+  sugar.
 
 
 * Component interfaces


<--  Date Index  --> <--  Thread Index  -->

Reply via email to:

Powered by MHonArc.

Copyright © 2006-2007, OW2 Consortium | contact | webmaster.