libapache2-mod-raii

C++ application server module for apache2

This page is also available in engrish

Description

Il s'agit d'un module pour apache2 qui permet la compilation, le chargement et l'exécution de classes écrites en C++ et de pages html avec du C++ dedans. Je travaille sur ce module depuis plus de 4 ans et l'utilise en production sur plusieurs applications (aussi bien à titre professionnel que personnel). C'est stable et plutôt réactif. Le développement d'applications web est très agréable et assez rapide.

Voici une liste des fonctionnalités et spécificités.

Tel que le module est aujourd'hui :

 

Mais pourquoi

Parce que j'ai trouvé le concept de j2ee intéressant, parce que l'environnement permettant de faire fonctionner un serveur d'application java n'est pas à la portée d'un Cobalt qube qui n'a que 64Mo de mémoire (D'ailleurs essayez de faire tourner un site php sur un qube... mouarf! et ne parlons pas de RoR... snif). Et parce qu'il fallait que je me lance dans le C++, depuis le temps que je me le disais ! Par ailleurs, et même si on peut faire un tas de choses ave J2EE, je n'aime pas trop le langage Java.

Mais encore

L'api ressemble à celle fournie par javax.servlet.http. Mais contrairement à Java, C++ ne dispose pas de Garbage Collector, il faut voir ceci comme un avantage car l'utilisation de pointeurs intelligents à comptage de références permet de gérer de façon sûre les allocations mémoire (cf L'idiome Raii).

Prérequis

Une debian, à partir de etch (testé sur mips(el), powerpc et i386), avec les paquets g++, libapache2-mod-apreq2, libapreq2, libapreq2-dev, apache2-mpm-worker, apache2-threaded-dev, libapr1, libapr1-dev, libvmime0, et libvmime-dev. Pour les connecteurs  libsqlite0, libsqlite0-dev, sqlite, libsqlrelay-0.39, sqlrelay-dev,libpq5 et libpq-dev.

cobalt:~# apt-get install g++ libapache2-mod-apreq2 libapreq2 libapreq2-dev \
apache2-mpm-worker apache2-threaded-dev libsqlrelay-0.39 \
sqlrelay-dev libapr1 libapr1-dev libvmime0 libvmime-dev \
libsqlite0 libsqlite0-dev sqlite libpq5 libpq-dev bison flex

Screenshot

Enfin pas une capture d'écran mais des morceaux de programmes.

un contrôleur ( /ctrl.C ) :

#include <raii.H>

using namespace raii;
using namespace raii::sql;

class SERVLET(index) : public HttpServlet {


void service( HttpServletRequest& request, HttpServletResponse& response) {

String action=request.getParameter("action");

if ( action.empty() || action == "index" ) {
request.setAttribute("my_attr",
new String( String("hello ")
+ request.getParameter("name") + "!" ) );
request.getRequestDispatcher("/view/index.csp").forward(request,response);
}
else if ( action == "plop" ) {
//do something
}
else {
throw ServletException("Unknown action");
}
}
};

exportServlet(index);

une vue ( /view/index.csp ) :

<%
ptr my_attr=request.getAttribute("my_attr");
if ( ! my_attr )
throw ServletException("plop");
%>
bonjour <%= *my_attr %><br/>
hello <%= request.getRemoteAddr() %> !

<table>
<tbody>
<tr>
<th>header</th><th>value</th>
</tr>
<%
Vector<String> headers=request.getHeaderNames();
for ( Vector<String>::const_iterator it=headers.begin();
it != headers.end();
++it) {
%>
<tr>
<td><%= *it %></td>
<td><%= request.getHeader(*it) %></td>
</tr>
<% } %>
</tbody>
</table>

ou avec un tag perso

<%:table<Vector<String> > in=request.getHeaders(); th="header"; th="value"; cond=self.begin()%>
<tr>
<td><%= *self.elem %></td>
<td><%= request.getHeader(*self.elem) %></td>
</tr>
<%/table<Vector<String> > self.next() %>
<%
response << "PLOP!";
%>

Téléchargement

Vous pouvez téléarcher au choix les sources ou les paquets debian pour i386 (ça marche aussi sans problème sur mipsel et powerpc)(LGPL 2.1).

Installation depuis les sources

$ tar xvfz libapache2-mod-raii-XXX.tgz
$ cd libapache2-mod-raii-XXX
$ SU0=su0 make install

si vous n'avez pas su0 :

$ make
$ su -c "make install"

ou pour construire le paquet debian

$ tar xvfz  libapache2-mod-raii-XXX.tgz
$ cd libapache2-mod-raii-XXX
$ fakeroot debian/rules binary

ensuite il faut indiquer à apache qu'il y a un nouveau module à charger (sans oublier d'activer apreq)

# cat > /etc/apache2/mods-available/raii.load
LoadModule raii_module /usr/lib/apache2/modules/mod_raii.so
SegfaultHandler on
^D
# a2enmod apreq
# a2enmod raii

Installation du paquet debian

# dpkg -i libapache2-mod-raii_XXX_ARCH.deb
# a2enmod apreq
# a2enmod raii

Configuration

Du fait du fonctionnement de ce module, il faut impérativement utiliser la version mpm-worker d'apache et ne lancer qu'un seul processus serveur. En revanche, il n'y a pas de limitation concernant le nombre de threads (modulo la mémoire utilisée par chaque thread pour la pile). Ce qui donne dans le fichier /etc/apache2/apache2.conf

 StartServers         1
ServerLimit 1
ThreadLimit 25
MaxClients 25
ThreadsPerChild 25
MinSpareThreads 5
MaxSpareThreads 15
MaxRequestsPerChild 0

puis enfin redémarrer apache :

# apache2ctl restart

Et ensuite ?

Vous pouvez installer Not So Original, une galerie photo, TinyCMS ou loudspeaker.

À l'aide !

En cas de problème, n'hésitez pas à me glisser un mail. guillaume sur ce domaine.