Mail Archive Home | fractal-commits List | May 2008 Index
| <-- Date Index --> | <-- Thread Index --> |
Cecilia Comanche example: first chunk of the conversion from LyX to APT.
--- sandbox/debrouxl/comanche/src/site/apt/index.apt 2008-05-28 09:24:36 UTC (rev 7803)
+++ sandbox/debrouxl/comanche/src/site/apt/index.apt 2008-05-28 09:38:09 UTC (rev 7804)
@@ -1,21 +1,38 @@
-----
Cecilia Comanche example
-----
+ Eric Brunteton, Lionel Debroux.
+ -----
- TODO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Overview
+ This tutorial is an introduction to the Fractal component model. It explains
+ informally how to {{{#Design}design}}, {{{#Implementation}implement}} and
+ {{{#Configuration}deploy}} component-based applications with Fractal (and with
+ some associated tools), in C, by using a concrete example, namely an extremely
+ minimal web server.
+
+ Before going through this tutorial, you should have gone through the
+ {{{../helloworld/index.html}Hello World tutorial}}.
+
+ This document is intended for those that do not know Fractal, and want to get
+ an overview of this component model, of its motivations and benefits. If you
+ are in this case, you should read this document first, before reading the
+ Fractal component model specification.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Download
To get sources of the Comanche example based on <<Makefile>>, download one of
- the following package:
+ the following packages:
* {{{downloads/${project.build.finalName}-makefile.tar.gz}${project.build.finalName}-makefile.tar.gz}}
* {{{downloads/${project.build.finalName}-makefile.zip}${project.build.finalName}-makefile.zip}}
To get sources of the Comanche example based on <<Maven>>, download one of the
- following package:
+ following packages:
* {{{downloads/${project.build.finalName}-mvn.tar.gz}${project.build.finalName}-mvn.tar.gz}}
@@ -24,7 +41,331 @@
Instructions for compiling and running the example, see the <<<README.txt>>>
file.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Introduction
+* What is Fractal?
+
+ Fractal is a modular and extensible component model that can be used with
+ various programming languages to design, implement, deploy and reconfigure
+ various systems and applications, from operating systems to middleware
+ platforms and to graphical user interfaces. Fractal is also a project with
+ several sub projects, dealing with the definition of the model, its
+ implementations, and the implementation of reusable components and tools
+ on top of it.
+
+ The Fractal component model heavily uses the <<separation of concerns>>
+ design principle. The idea of this principle is to separate into distinct
+ pieces of code or runtime entities the various <concerns or aspects> of an
+ application: implementing the service provided by the application, but also
+ making the application configurable, secure, available, ...\
+ In particular, the Fractal component model uses three specific cases of the
+ separation of concerns principle: namely <separation of interface and
+ implementation>, <component oriented programming>, and <inversion of
+ control>.\
+ The first pattern, also called the bridge pattern, corresponds to the
+ separation of the design and implementation concerns.\
+ The second pattern corresponds to the separation of the implementation
+ concern into several composable, smaller concerns, implemented in well
+ separated entities called components.\
+ The last pattern corresponds to the separation of the functional and
+ configuration concerns: instead of finding and configuring themselves the
+ components and resources they need, Fractal components are configured and
+ deployed by an external, separated entity.
+
+ The separation of concerns principle is also applied to the structure of
+ the Fractal components. A Fractal component is indeed composed of two
+ parts: a <content> that manages the functional concerns, and a
+ <controller> that manages zero or more non functional concerns
+ (introspection, configuration, security, transactions, ....).\
+ The content is made of other Fractal components, i.e. Fractal components
+ can be <nested> at arbitrary levels (Fractal components can also be
+ shared, i.e. be nested in several components at the same time).\
+ The introspection and configuration interfaces that can be provided by
+ the controllers allow components to be deployed and reconfigured
+ dynamically.\
+ These control interfaces can be used either programmatically, or through
+ tools based on them, such as deployment or supervision tools.
+
+ More information about Fractal, including the complete specification of the
+ component model, and several tutorials, can be found at {{{http://fractal.objectweb.org}http://fractal.objectweb.org}}.
+
+* Summary
+
+ The main characteristics of the Fractal model are recursion, reflexion and
+ sharing. The Fractal project is made of four sub projects: model,
+ implementations, components and tools.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-TODO
+Design
+ Before programming a component based software system with Fractal, one must
+ first <design> it with components and, in particular, identify the components
+ to be implemented.\
+ Note that this <component oriented design> task is quite independent from the
+ subsequent <component oriented programming> task: 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 (but then, of course, one loses
+ the advantages of <component oriented programming>: modularity,
+ adaptability, ...).
+
+ This section explains how to design component based applications, by using a
+ concrete example. The next sections reuse this example to illustrate how to
+ implement and deploy Fractal component based applications. This example
+ application is Comanche, an extremely minimal HTTP server. A classical,
+ non component oriented, threaded implementation of this application, in
+ pseudo-code, is shown below:
+
++------------------------------------------------------------------------------+
+Server {
+ Socket server_socket;
+ Socket worker;
+
+ while true do
+ server_socket = create server socket
+ worker_socket = accept(server_socket, port)
+ // accept is a blocking call, it returns only when it has accepted a connection
+ create new worker thread, passing it worker_socket
+ end while
+}
+
+WorkerThread {
+ read request on socket
+
+ print first line of request
+ // analyse request
+ if (request starts with "GET /") then
+ get actual filename
+ // up to the second " " of the first line of a well-formed request
+
+ if ((file exists) and (file is not special, e.g. a directory)) then
+ write "HTTP/1.0 200 OK\n\n" to socket
+ write contents of file to socket
+ else
+ write "HTTP/1.0 404 Not Found\n\n" to socket
+ write e.g. "<html> Document not found.</html>" to socket
+ end if
+ end if
+ close socket
+}
++------------------------------------------------------------------------------+
+
+ As can be seen from the source code, this server accepts connections on a
+ server socket and, for each connection, starts a new thread to handle it.
+ Each connection is handled in two steps: the request is analyzed and logged
+ to the standard output, and then the requested file is sent back to the
+ client (or an error is returned if the file is not found).
+
+* Finding the components
+
+ In a component based application, some components are <dynamic>, i.e they can
+ be created and destroyed dynamically, possibly quite frequently, while other
+ components are <static>, i.e. their life time is equal to the life time of
+ the application itself. The dynamic components generally correspond to <data>,
+ while the static ones generally correspond to <services>.
+
+ In order to identify components in an application, it is easier to begin by
+ identifying its static components. In other words, one should begin by
+ identifying the services that are used in the application.\
+ In the case of Comanche, we can immediately identify two main services, namely
+ a request receiver service and a request processor service. But it is also
+ possible to identify other, lower level services.\
+ For example, we can see that the request receiver service uses a thread
+ factory service, to create a new thread for each request. This thread factory
+ service can be generalized into a scheduler service that can be implemented
+ in several ways: sequential, multi thread, multi thread with a thread pool,
+ and so on.\
+ Likewise, we can see that the request processor uses a request analyzer
+ service, and a logger service, before effectively responding to a request.
+ This response is itself constructed by using a file server service, or an
+ error manager service. This can be generalized into a request dispatcher
+ service that dispatches requests to several request handlers sequentially,
+ until one handler can handle the request (we can then imagine file handlers,
+ servlet handlers, and so on).
+
+ The caller graph & call graph extraction functionality of the powerful
+ {{{http://www.doxygen.org}Doxygen}} tool (free software) can help determining
+ services.
+
+ After the services have been specified, one can look for the main data
+ structures, in order to identify the dynamic components. But the
+ identification of the dynamic components is not mandatory, and is generally
+ not done, because dynamic components themselves are rarely used (this means
+ that, at programming time, data structures are generally not implemented as
+ components, but as ordinary <struct>s).\
+ Indeed components do not have many benefits in the case of highly dynamic,
+ short lived structures (introspection and dynamic reconfiguration, for
+ instance, are not very useful in this case). In the case of Comanche we
+ can consider sockets, HTTP requests, files, streams, and even threads as
+ such data structures. But we will not map them to dynamic components.
+
+ After the services have been specified, one must assign them to components.
+ Each component can provide one or more services but, unless two services
+ are very strongly coupled, it is better to use one component per service.\
+ In the case of Comanche, we will use one component per service. We
+ therefore have the seven following components: request receiver, request
+ analyzer, request dispatcher, file request handler, error request handler,
+ scheduler and logger.
+
+* Defining the component architecture
+
+ After the components have been identified, it is easy to find the
+ dependencies between them, and to organize them into composite components.
+ Indeed the service dependencies are generally identified at the same time
+ as the services themselves. If it is not the case, dependencies can also
+ be found by looking at some use cases or scenarios.\
+ Likewise, services are generally identified from high level to lower level
+ services (or vice versa). It is then easy to find the dependencies and the
+ abstraction level of each component, since the components correspond to the
+ previous services.
+
+ This is particularly clear in the case of Comanche: indeed, by re-reading the
+ previous section, one can see that the service dependencies have already been
+ identified. For example, the request receiver service uses the scheduler
+ service and the request analyzer, the request analyzer uses the request
+ dispatcher, which itself uses the file and error request handlers.\
+ One can also see that the abstraction levels have already been found: the
+ request receiver is ``made of'' the request receiver itself, plus the
+ scheduler; the request processor is made of the request analyzer, the
+ logger, and the request handler; the request handler is itself made of the
+ request dispatcher, and of the file and error request handlers. All this can
+ be summarized in the following component architecture:
+
+[archi-cecilia.png] Architecture of the Cecilia Comanche example.
+
+* Defining the component contracts
+
+ After the services have been found and organized into components, and after
+ the component hierarchy and the component dependencies have been found, only
+ one thing remains to be done to finish the design phase, namely to define
+ precisely the contracts between the components, at the syntactic and semantic
+ level (if possible with a formal language - such as pre and post conditions,
+ temporal logic formulas, and so on). Classical object oriented design tools,
+ such as scenarios and use cases, can be used here.
+
+ The component contracts must be designed with care, so as to be the most
+ stable as possible (changing a contract requires to change several components,
+ and is therefore more difficult than changing a component). In particular,
+ these contracts must deal only with the services provided by the components:
+ nothing related to the implementation or configuration of the components
+ themselves should appear in these contracts.\
+ For example, a <<<setLogger>>> operation has nothing to do in a component
+ contract definition: this operation is only needed to set a reference between
+ a component and a logger component. In other words, contracts must be defined
+ with <<separation of concerns>> in mind (see section {{{#Introduction}Introduction}}):
+ contracts must deal only with functional concerns; configuration concerns
+ will be dealt with separately, as well as other concerns such as security,
+ life cycle, transactions...
+
+ In the case of Comanche, we will use minimalistic contracts, defined in
+ Cecilia IDL:
+
+ * The logger service will provide a single <<<log>>> method, with a single
+ parameter representing a string;
+
+ * The scheduler component will provide a single <<<schedule>>> method, with a
+ single parameter representing a pointer to a <<<struct>>> containing a way
+ to run a function with its parameters (function pointer + pointer to
+ arguments), and also possibly other implementation-defined data.\
+ The role of this schedule method is to execute the given entity at some time
+ after the method has been called, possibly in a different thread than the
+ caller thread;
+
+ * The request analyzer, the request dispatcher and the file and error request
+ handlers will all provide a single <<<handleRequest>>> method, with a single
+ parameter representing a socket file descriptor or a <<<char *>>>. This
+ single handleRequest method will be implemented in several ways, in the
+ different components:
+
+ * the request analyzer will read the request to get the requested URL;
+
+ * the request dispatcher will forward each request to its associated
+ request handlers, sequentially, until one request handler successfully
+ handles the request;
+
+ * the file request handler will try to find and to send back to the client
+ the file whose name corresponds to the requested URL, if it exists;
+
+ * the error request handler will send back to the client an error message,
+ and will always succeed.
+
+* Summary
+
+ The first step to design a component based application is to define its
+ components. This is done by finding the <services> used in this application.\
+ The second step is to find the dependencies and hierarchical levels of these
+ components.\
+ The last step is to define precisely the contracts between the components.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Implementation
+
+* Choosing the components' granularity
+
+* Implementing the component interfaces
+
+* Implementing the components
+
+* Summary
+
+ Components must be implemented with an appropriate granularity, resulting from
+ a compromise between adaptability and performance.\
+ Their interfaces must be separated from their implementation (this rule must
+ also be applied for data structures).\
+ The implementation must not contain explicit dependencies to other components
+ to allow both static and dynamic (run-time) reconfigurations.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Configuration
+
+* ADL based configuration
+
+* Summary
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Conclusion
+
+ The Fractal component model uses well known design patterns, and organizes
+ them into a uniform, language independent model, that can be applied to
+ operating systems, middleware platforms or graphical user interfaces.
+
+ The Fractal component model brings several benefits:
+
+ * it enforces the definition of a good, modular design;
+
+ * it enforces the separation of interface and implementation, which ensures a
+ minimum level of flexibility;
+
+ * it enforces the separation between the functional, configuration and
+ deployment concerns, which allows the application's architecture to be
+ described separately from the code, for example by using an Architecture
+ Description Language;
+
+ * it allows applications to be instantiated in various ways (from fully
+ optimized but unreconfigurable configurations to less efficient but fully
+ dynamically reconfigurable configurations).
+
+ []
+
+ All these features should reduce the development time, and should also
+ increase the reusability of components and component architectures, i.e.
+ they should increase productivity.
+
+ The Fractal component model and its associated tools have already been used
+ successfully in a number of applications such as:
+
+ * <<THINK>>, a library of Fractal components to build operating system
+ kernels;
+
+ * <<Speedo>>, an implementation of the Java Data Object (JDO) specification;
+
+ * <<Proactive>>, a middleware for parallel, distributed and multi-threaded
+ computing;
+
+ * <<Petals>>, a large middleware for Enterprise Application Integration.
+
+ []
+
+ More information about Fractal, including the complete specification of the
+ component model, and several tutorials, can be found at
+ {{{http://fractal.objectweb.org}http://fractal.objectweb.org}}.
--- sandbox/debrouxl/comanche/src/site/resources/archi-cecilia.png (rev 0)
+++ sandbox/debrouxl/comanche/src/site/resources/archi-cecilia.png 2008-05-28 09:38:09 UTC (rev 7804)
@@ -0,0 +1,14 @@
+\x89PNG
+
++\xF3Օ\x86\xC6\xD8!\x82\x81\xCBX\xE1Q\x86~\xED"\xD3Y-\xEF9\xB2\xC82ɒ.F\xC05f\xE040\xE0<\x96CXC;\xC4\xF7\xEAK\xAD\xB3\x9Cw\x9D?\A\xA4\x89\xBF\xB8Jx\xB7W\xE0:\xC0\xA0l,\x87\xB0\x96\xF9B\xF7\N\x8D\xD5J\xE9\x9EsG\x98R*\xE9B\xB8\xE6\xAC\xD6\xC4rf}\xA3\xE9ב\x8E`Ei7\xB6\xAF\x84t\xFB\x8Eg)\x87\xC2k_\x87|ir\xBF}\xFB\xADwϖ;\xD6g\xFA
+l\xE4qN\x88\xD9Өk\xB2]2/\xFAx\xF2\xBDo\xFE\xF4\xDBī\x9F\xE6:4%r̕!\x87\xD8Ȱ.t톣\xE1\x98;;l\xD3]\xDA\xDCM7D\x93ʮ&\xDF\xE07\xCFPW\xD7Ռ9\xB8\xC1U\xC3\xE47\xA4\xE6\xFEא\xB4\x8BK\xD4א\xA4\xEBp\xA6\x8B\x8E\xA4\xB9K7\x8E\xC9t\xB7*<\xABo\x91\xF3\xBC5\xAE\x9C\xB9}\x89~u\x97\xBB5',\xEDn\x95\xF3\xB1\xEE\xAC\xC8\xE1nt\xE8\xE2\xEEF\x87\xFEXw\xA3\xA0\xF2\xEE\xAC\xCC\xD2\xEEb
+uĽf^\xB6LG\xD6\xEBN\xA5\x84\xEFX\xDFȅk\xDDxO\xA9\xE0F\xCB\xFB`7ڡ+\xB8ю\xF5\xC1n\xB4C\xD7pc~\xB2\xEBП\xEC\xC6:t
+\xF7ѡ\xA5\xF0?ݫw\xD7s\xE1\x98{\xF0\xC3\xFDC\xEEX"8\x82\xA44\xC0\xC7!Ŧ˿N\xB9c\xC72֓\xDC\xEDv\xEB{\xB9۳\x9E\xEF2W\xCD%\xC1,'C}M5w\xECK\xD2uT"N\xBBz\xED\xB92\xD4q\xE1&w)?\xDB]G\xE8|\xD7 \xF12ݡc\x85\xF9
+>\xE5:7\xEB\x9En\xC8dϹ\x96<\xD7\xEA3\\xB8\xC0\xC5@\xB3]{E}!\xEC6\xA8\xE9\xF6@\xA7\xF7\xC5Q\xEF\x81:\x92\xEDڷ\xDDE:\xEA\xFA\x8B\xE0-\xAES\xEEb\x97\xD0{n\xDFe\xB8\xAF]B\x8B\xE8\xBA\W9\xEC\xCA,\xD7\xF0\x8EI)nx\xAE\xC9q\xB1d\xC0\x90^\xD6\xF7\x9C;\xDFj\x92t\xF8!\xCCn\x9F\xE3\xA5\x80\xB2\xD8u\xD6\xCD\xE9Ϝr\xD2IIc\xAE-\xE7\x86's\xD7\xF7\xB5\x8E$˺\xAB
+X\xBE\x93c`\xB2+\\xDFUr\xCE\xFA\xCE\xA6\xBE\xEB':L
+\xD7º\xAEo_\xD2Dk\xBB\xD3\xF5]U\xD8}X\xE1\xAB,\xE4>\x9E\xCE]Q\xC1\xF5GJ$ƒN\xFB\xF8L
+_\xF8\xB8\x81M\xD58\xCF8\xB7R\xF7@^W$\xA3\xEA\xB8L[\xAE\xE0W\xB4t\xE4\xBC{|~d\x90\xB1\xFA\xF6\xED\xA6\xF6\xB5\
xE29\xF8\xE1\xF9\xEE2\xED\xB9\xFDj \\xF7\xFA\xC8kw\x8Bl\xC25b~\xB0C|\xC6>l̍\xBB\xE3\xC8½\xE9.\xD3P\x92\xBF1
+\\xF2\xCD\xF3̱*\xF8w\xE0\xEE(8˅\x87\x8B\xBD;l\x90\xD8p\xFD\xBC\x9C\xF9ץ/\xAB\xEFp\x9A\xC7\xEB\xA0w\x87\x8D\xD7.\p\xE7]\xF3\xE5\xD3ѱ ?\xD8CBt\xA7}W\xE9\xF3\xEE,\xA3\x98\xFE\x90|\xFF:\x82\xA5\xF2VFv\x97\x9Fr\xC7\xD3|>n\x9CvOOΏ\xDEp!\x92\xBD\x82\xFB8\xCD\xF5\xDDh\xF7\xAC\xE0\xC2=n\xF44G\xDC\xFC\xFB%\xF7\xDDxX\xBB\xD9)\xE1\xC2=n8͋{V\x8A\xBBᱛ\x8F\xAEw\xE1\x85\xC1\xB5\xD8m\xB8\xAFM:x\xEE\x8A\xE0b\xD0\xCE\xCE2]\xE5>\xD2o)\xE6. \xAE-\xEA\xFEZ\xBCuD\xB8\x9F\xC8\xF5\xA4h}\xBF\xBC\x8F\xC8\xEB\xA1A\x85\xDA7\xEE\xC6o\xA0*\xEFƷUp\x9Fs\x95\xD4u\xFFr\xF7\xB1R\xE3\x9C\xCB\xDDg\x85\xEB\xBB\xC7\xC6u\x8F
+\xDF\xE0>\xE6\xF5\xDD\xC7\xFC\xE8\xF9\x9B\xADu\xC2\xEE;R\xEB\xB1\xB8_\xE7G\xE3=\x9C\xA9\xF5\xD8\xDCu26\xB9[\xC4\xED\xBB\xE4zl\xD4zl\x93\xD4zl\xF7q?\xCE\xDEzlw1\x9A\xAC\xE9ֈWͽ\xD3M\xACO~\x9E\xBB\xBF.Z\xCE\xDD_-\xE8\x96s\xF7\xD7E\x8B\xB9\x89u\xD1bnx\xF83\xDC\xF2.v\xA7\xDD9!@Uq\xA7\xEF\xF0\xA9\xEEJAbcK\xC21\x81\xB1\x8E\xAB\xC0\x87C\xA1 \xC6:\xAEQ^\xF3U\x81\xB1\x8Ak8\xA5\x9CI\xA4B`\xAC\xE2\xFFĨ.\xB9\xC9=\x94\xA9\xB9\xEF\xB8g\xEFy\xD7=\x9E\xDEw\x87e\xE8\xD3_\x9Au\xB5p\x97\x8B\xB1N\xED(\xE0JA\xADN\xED(\xE0\xA0\xE1;\xE4\xEA\xBB\xDA8\x9D\xDAP\xC0Ea\x94\xDAP\xC0=\x97\x9A\xDB\xDC\xEF\xE8\xBC\xF2\xAD\xD2\xF2\xFB\x90릗k\xC8\xF3\xA2\xAE;\\xD1\xEEpE\x8F%5\x88$ә\xAEt\x9D\xB3\xDA2</\xD6^\xE26܂ZՅ\xC16܂Z\xFD\xAB\x8E⮣u۷vj\xEEOp\xEF\xFA\xFFb\xEEH\xCDmns\x9B\x9B\xED\xFE\x8Ao\xD7\xDDJ>\ No newline at end of file
| <-- Date Index --> | <-- Thread Index --> |
Powered by MHonArc.
Copyright © 2006-2007, OW2 Consortium | contact | webmaster.