Le blog à FredBlog about programming and few other hobbies
Mon blog sur la programmation et autres petits trucs2024-03-06T15:37:00+01:00Fredurn:md5:aa8fdbf61072948b94b6b73fbda45c54DotclearWhy you should define your own typesurn:md5:ec161315b94fc648fa5a724c38ed712a2016-02-10T13:38:00+01:002016-02-12T00:44:22+01:00FredDéveloppementAdaJava <p>Most of the people coming here know that I'm an Ada enthusiast.<br />
In my job, I'm mostly developing in Java and one of the remarks I got in the past about Ada type system is that it's useless.<br />
A lot of developers are arguing that they never have bugs due to a type error. So, the use of range constraints and so on in Ada are almost seen as useless verbosity.<br />
For once, I've another point of view about this feature and it's not related to bugs but to maintainability.<br />
<br /></p>
<h4>The reason</h4>
<p>It's not really a secret that I'm working on cartographic products. Our product is written in Java and we use <a href="http://openmap-java.org/" hreflang="en">OpenMap</a> for displaying some kind of maps.<br />
Few weeks ago, we found that the old version of OpenMap we were using contained a bug about a specific raster format. After looking into the new source code<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#pnote-639-1" id="rev-pnote-639-1">1</a>]</sup>, I found that the bug was still there.<br />
One of my colleague fixed it and provided a patch to the project. Then I decided to test the patch on the brand new version of OpenMap by migrating to the last version.<br />
<br /></p>
<h4>The problem</h4>
<p>Migrating is not always as simple as it might seem.<br />
Between the two versions, 4.6.5 and 5.1.13, there has been a lot of changes that were easily detected by the compiler but the main one only seemed to be a package name change.<br />
The <em>LatLonPoint</em> class was in the past inside the package <em>com.bbn.openmap</em> and changed to <em>com.bbn.openmap.proj.coords</em>.<br />
Ok, that's easy but if I show you the beginning of the code, you will see.<br /></p>
<pre class="java java" style="font-family:inherit"><span style="color: #666666; font-style: italic;">/*
* For version 4.6.5
*
*/</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LatLonPoint <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Cloneable</span>, <span style="color: #003399;">Serializable</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// SOUTH_POLE <= phi <= NORTH_POLE</span>
<span style="color: #666666; font-style: italic;">// -DATELINE <= lambda <= DATELINE</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">float</span> NORTH_POLE <span style="color: #339933;">=</span> 90.0f<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">float</span> SOUTH_POLE <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>NORTH_POLE<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">float</span> DATELINE <span style="color: #339933;">=</span> 180.0f<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">float</span> LON_RANGE <span style="color: #339933;">=</span> 360.0f<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// initialize to something sane</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">float</span> lat_ <span style="color: #339933;">=</span> 0.0f<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">float</span> lon_ <span style="color: #339933;">=</span> 0.0f<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">float</span> EQUIVALENT_TOLERANCE <span style="color: #339933;">=</span> 0.00001f<span style="color: #339933;">;</span></pre>
<p>And the newest one</p>
<pre class="java java" style="font-family:inherit"><span style="color: #666666; font-style: italic;">/*
* For version 5.1.13
*
*/</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> LatLonPoint <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Point2D</span> <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Cloneable</span>, <span style="color: #003399;">Serializable</span> <span style="color: #009900;">{</span>
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
*
*/</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 4416029542303298672L<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">double</span> NORTH_POLE <span style="color: #339933;">=</span> <span style="color: #cc66cc;">90.0</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">double</span> SOUTH_POLE <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>NORTH_POLE<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">double</span> DATELINE <span style="color: #339933;">=</span> <span style="color: #cc66cc;">180.0</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">double</span> LON_RANGE <span style="color: #339933;">=</span> <span style="color: #cc66cc;">360.0</span><span style="color: #339933;">;</span></pre>
<p><br />
Do you see ?<br />
First of all, the class is now abstract... You can imagine what happened in my code as this class is really centric <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
So how do you create <em>LatLonPoint</em> ?<br />
Inside the <em>LatLonPoint</em>, you have two inner classes defined as follows</p>
<pre class="java java" style="font-family:inherit"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> <span style="color: #003399;">Float</span> <span style="color: #000000; font-weight: bold;">extends</span> LatLonPoint <span style="color: #009900;">{</span>
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
*
*/</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>2447464428275551182L<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">float</span> lat<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">float</span> lon<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">transient</span> <span style="color: #000066; font-weight: bold;">float</span> radLat<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">transient</span> <span style="color: #000066; font-weight: bold;">float</span> radLon<span style="color: #339933;">;</span>
<span style="color: #009900;">[</span>...<span style="color: #009900;">]</span>
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
* Double precision version of LatLonPoint.
*
* @author dietrick
*/</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> <span style="color: #003399;">Double</span> <span style="color: #000000; font-weight: bold;">extends</span> LatLonPoint <span style="color: #009900;">{</span>
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
*
*/</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>7463055211717523471L<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">double</span> lat<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">double</span> lon<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">transient</span> <span style="color: #000066; font-weight: bold;">double</span> radLat<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">transient</span> <span style="color: #000066; font-weight: bold;">double</span> radLon<span style="color: #339933;">;</span></pre>
<p>This was done to mimic the <em>Point2D</em> class but everywhere I instanciated a <em>LatLonPoint</em>, I now need to choose between <em>Float</em> or <em>Double</em> version.<br />
Ok but what happens if I prefer to keep the higher abstract view ?<br />
Well, for getting latitude in degrees the type returned is <em>float</em> whereas for radians, it's <em>double</em>.<br />
Mixing such kind of types creates a mess inside our application because everything was <em>float</em> in the past.<br />
<br /></p>
<h4>The Ada solution</h4>
<h3>First try</h3>
<p>A first solution might be to declare types for latitude, longitude and radians.</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">type</span> Latitude <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">digits</span> <span style="color: #ff0000;">10</span> <span style="color: #46aa03; font-weight:bold;">range</span> -<span style="color: #ff0000;">90.0</span> .. <span style="color: #ff0000;">90.0</span>;
<span style="color: #46aa03; font-weight:bold;">type</span> Longitude <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">digits</span> <span style="color: #ff0000;">11</span> <span style="color: #46aa03; font-weight:bold;">range</span> -<span style="color: #ff0000;">180.0</span> .. <span style="color: #ff0000;">180.0</span>; <span style="color: #adadad; font-style: italic;">-- for 7 digits after dot</span>
<span style="color: #46aa03; font-weight:bold;">type</span> radian <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">digits</span> <span style="color: #ff0000;">15</span> <span style="color: #46aa03; font-weight:bold;">range</span> -<span style="color: #ff0000;">2</span>*π .. <span style="color: #ff0000;">2</span>*π; <span style="color: #adadad; font-style: italic;">-- with π from Ada.numerics</span>
<span style="color: #46aa03; font-weight:bold;">type</span> LatLonPoint <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>; <span style="color: #adadad; font-style: italic;">-- which should define the way we store the coordinates</span></pre>
<p>The problem is that the client code don't have any way to change the precision the same way Java more or less allows it.<br />
It's time to extend the functionalities with <a href="https://en.wikibooks.org/wiki/Ada_Programming/Generics" hreflang="en">generics</a>.<br /></p>
<h3>Second try</h3>
<p>It would be better for the client code to define the precision.<br />
Here is one solution... But I'm sure there's something clever than this<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#pnote-639-2" id="rev-pnote-639-2">2</a>]</sup></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">generic</span>
<span style="color: #46aa03; font-weight:bold;">type</span> real <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">digits</span> <>;
<span style="color: #46aa03; font-weight:bold;">package</span> coords <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">type</span> latitude <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> real <span style="color: #46aa03; font-weight:bold;">range</span> -<span style="color: #ff0000;">90.0</span> .. <span style="color: #ff0000;">90.0</span>;
<span style="color: #46aa03; font-weight:bold;">type</span> longitude <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> real <span style="color: #46aa03; font-weight:bold;">range</span> -<span style="color: #ff0000;">180.0</span> .. <span style="color: #ff0000;">180.0</span>;
<span style="color: #46aa03; font-weight:bold;">type</span> radian <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> real <span style="color: #46aa03; font-weight:bold;">range</span> -<span style="color: #ff0000;">2</span>*π .. <span style="color: #ff0000;">2</span>*π; <span style="color: #adadad; font-style: italic;">-- with π from Ada.numerics</span>
<span style="color: #46aa03; font-weight:bold;">type</span> LatLonPoint <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>; <span style="color: #adadad; font-style: italic;">-- Using the types defined above</span>
<span style="color: #00007f;">end</span> coords;</pre>
<p><br />
You should wonder why not using Real types directly. First, because I want the compiler to check as much as possible.<br />
Second, because I don't need the precision of a Java double.<br />
Let me explain :<br />
With 7 digits after the dot for a latitude in decimal degrees, two latitudes in my code will be distant at equator level from 1 centimetre.<br /></p>
<h4>Conclusion</h4>
<p>By providing the precision on the client side through a generic unit, it is possible to avoid the types mixing we had with the Java version while keeping type safety.<br />
Changing precision is a client decision and not a implementer one. This way, the compilation problem<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#pnote-639-3" id="rev-pnote-639-3">3</a>]</sup> can be avoided.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#rev-pnote-639-1" id="pnote-639-1">1</a>] Open source is really great for this</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#rev-pnote-639-2" id="pnote-639-2">2</a>] Maybe because I wrote it after drinking wine with another Ada enthusiast :D</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#rev-pnote-639-3" id="pnote-639-3">3</a>] Around 1500 compilation errors in my software</p></div>
http://frederic.praca.free.fr/index.php?post/2016/02/10/Why-you-should-define-your-own-types#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/639Joujou à la modeurn:md5:522e3e861b3eb50422ef651dd5ff25722015-08-15T16:47:00+02:002015-08-15T17:44:59+02:00FredDéveloppement <p>Et voilà, j'ai craqué.<br />
Après avoir lu une série d'articles sur l'utilisation d'Ada dans les microcontrolleurs (comme <a href="http://blog.adacore.com/how-to-prevent-drone-crashes-using-spark" hreflang="en">celui-ci</a>, <a href="http://electronicdesign.com/blog/running-ada-2012-cortex-m4" hreflang="en">celui-là</a> ou enfin encore <a href="http://www.embeddedrelated.com/showarticle/585.php" hreflang="en">ça</a>), je me suis jeté à l'eau et j'ai fini par acheter une carte <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320" hreflang="en">Nucleo</a> de chez ST Microelectronics.<br />
Cette petite carte a tout plein de trucs intéressants comme plein de <em>timers</em>, une bonne tripotée d'entrées-sorties digitales et analogiques mais surtout, elle est compatible avec l'Arduino au travers d'un connecteur ad hoc.<br />
<br />
Me voici donc parti pour du développement en Ada sur la bête.<br />
J'ai donc téléchargé GNAT pour ARM sur le site d'<a href="http://libre.adacore.com/download/configurations" hreflang="en">Adacore</a> et c'était parti.<br />
Sauf que mes premiers essais furent infructueux, jusqu'à ce que je comprenne que le <em>runtime</em> fourni sous le nom <em>ravenscar-sfp-stm32f4</em> ne correspond pas à la famille STM32F4 complète mais seulement pour la carte <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF252419" hreflang="en">STM32F4DISCOVERY</a>. Dammed !!:)<br />
J'ai donc fouillé sur le Grand Ternet à la recherche d'un <em>runtime</em> avec l'appréhension de devoir faire un portage moi-même. Finalement, je n'ai rien eu à faire car j'ai trouvé le Graal sur GitHub<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#pnote-638-1" id="rev-pnote-638-1">1</a>]</sup> !!<br />
J'ai donc été sauvé par Nick Pascucci<a href="https://github.com/nickpascucci" hreflang="en"></a> qui a décidé il y a quelques mois d'effectuer le portage sur une carte Nucleo STM32F411RE, MA carte <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
<br />
L'histoire pourrait s'arrêter là si je n'avais commencé à lire le code du <em>runtime</em>... Sauf que c'est plus fort que moi, je lis du code.<br />
Si on revient un peu sur les raisons qui m'ont fait passer à Ada, on trouve :</p>
<ul>
<li>le typage fort,</li>
<li>le parallélisme intégré,</li>
<li>un super compilateur qui surveille tout ce que l'on fait à bon escient <sup>[<a href="http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#pnote-638-2" id="rev-pnote-638-2">2</a>]</sup> et</li>
<li>une grande lisibilité <sup>[<a href="http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#pnote-638-3" id="rev-pnote-638-3">3</a>]</sup></li>
</ul>
<p>Et là, dans le <em>runtime</em>, que vois-je ?<br /></p>
<pre class="ada ada" style="font-family:inherit">RCC.<span style="color: #202020;">PLLCFGR</span> := <span style="color: #ff0000;">16</span>#<span style="color: #ff0000;">2400</span>_3010#;
<span style="color: #adadad; font-style: italic;">-- Bit definitions for RCC APB1ENR register</span>
RCC_APB1ENR_USART2 : <span style="color: #46aa03; font-weight:bold;">constant</span> Word := <span style="color: #ff0000;">16</span>#0002_0000#;
RCC_APB1ENR_PWR : <span style="color: #46aa03; font-weight:bold;">constant</span> Word := <span style="color: #ff0000;">16</span>#<span style="color: #ff0000;">1000</span>_0000#;</pre>
<p>Des opérateurs logiques, des constantes qui nécessitent d'avoir la doc sous les yeux et du coup, des trucs aussi illisibles que si on faisait du C... Beurk !!<br />
J'ai donc fait mon psychorigide et j'ai <em>forké</em>. Bon, j'ai pas dit que c'était mieux mais moi, écrire des trucs comme ce qui suit, ça me correspond plus.</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #adadad; font-style: italic;">-- Enable clock for USART2</span>
RCC.<span style="color: #202020;">RCC_APB1ENR</span>.<span style="color: #202020;">USART2_Clock_Enable</span> := True;
<span style="color: #adadad; font-style: italic;">-- Enable clock for GPIOC</span>
RCC.<span style="color: #202020;">RCC_AHB1ENR</span>.<span style="color: #202020;">GPIOC_Clock_Enable</span> := True;
RCC.<span style="color: #202020;">RCC_APB2ENR</span>.<span style="color: #202020;">Sys_Config_Clock_Enable</span> := True;
<span style="color: #adadad; font-style: italic;">-- Configure PC13</span>
GPIOC.<span style="color: #202020;">MODER</span> <span style="color: #66cc66;">(</span><span style="color: #ff0000;">13</span><span style="color: #66cc66;">)</span> := Mode_IN;
GPIOC.<span style="color: #202020;">PUPDR</span> <span style="color: #66cc66;">(</span><span style="color: #ff0000;">13</span><span style="color: #66cc66;">)</span> := No_Pull;
<span style="color: #adadad; font-style: italic;">-- Select PC13 for EXTI13</span>
<span style="color: #adadad; font-style: italic;">-- See Page 139 of the RM0383 datasheet</span>
SYSCFG.<span style="color: #202020;">SYSCFG_EXTICR</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">4</span><span style="color: #66cc66;">)</span>.<span style="color: #202020;">Sources</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">1</span><span style="color: #66cc66;">)</span> := PORT_C;</pre>
<p>Alors oui, ça donne l'impression d'écrire plus de code et effectivement, cela fait plus de code assembleur dans certains cas mais au moins, ça se lit !<br />
<br />
Bon, en tout cas, si ça vous intéresse, c'est <a href="https://github.com/FredPraca/ravenscar-sfp-stm32f411-nucleo" hreflang="en">là</a>. Vous verrez que j'ai refait plein de choses, que j'ai redéfini des types et des énumérations pour tous les registres importants et que je continue <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#rev-pnote-638-1" id="pnote-638-1">1</a>] Et oui, rien n'est parfait dans ce bas monde</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#rev-pnote-638-2" id="pnote-638-2">2</a>] Au départ, je trouvais que c'était trop mais finalement, j'écris tellement de conneries que c'est bien :D</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#rev-pnote-638-3" id="pnote-638-3">3</a>] Même si certains diront que c'est vraiment trop verbeux</p></div>
http://frederic.praca.free.fr/index.php?post/2015/08/15/Joujou-%C3%A0-la-mode#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/638A l'abandonurn:md5:fb67465fb12de5c1d11cf3d33db477c42015-06-04T14:24:00+02:002016-02-15T19:00:11+01:00FredInformatique <p>Bon sang !!<br />
Ça fait maintenant plus d'un an que je n'ai rien publié <img src="/themes/default/smilies/sad.png" alt=":(" class="smiley" /><br />
Les raisons sont simples :</p>
<ul>
<li>moins de temps</li>
<li>moins de trucs super intéressants à partager</li>
<li>moins de développement de code</li>
<li>plus de guitare <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /> <sup>[<a href="http://frederic.praca.free.fr/index.php?post/2015/06/04/A-l-abandon#pnote-637-1" id="rev-pnote-637-1">1</a>]</sup></li>
</ul>
<p>Pourtant, c'est pas faute de lire plein de trucs. En vrac, voici quelques liens qui m'intéressent en ce moment :</p>
<ul>
<li><a href="http://www.embeddedrelated.com/showarticle/453.php" hreflang="en">Introduction to Microcontrollers</a> où je suis arrivé après avoir lu le lien suivant</li>
<li><a href="http://www.embeddedrelated.com/showarticle/625.php" hreflang="en">Introduction to Microcontrollers - Ada - 7 Segments and Catching Errors</a></li>
<li><a href="http://electronicdesign.com/dev-tools/armed-and-ready" hreflang="en">ARMed and ready</a></li>
<li><a href="http://electronicdesign.com/blog/running-ada-2012-cortex-m4" hreflang="en">Running Ada 2012 On The Cortex-M4</a></li>
<li><a href="http://blog.adacore.com/how-to-prevent-drone-crashes-using-spark" hreflang="en">How to prevent drone crashes using SPARK</a></li>
</ul>
<p><br />
Dans les problèmes qui m'empêchent aussi de publier, il y a aussi le fait que mon FreeBSD a fini par rendre l'âme... Par ma faute !<br />
Un passage à FreeBSD 10 et donc au compilateur <em>CLang</em> ont empêché certaines mises à jour de mes ports et quand j'ai voulu revenir à FreeBSD 9, j'ai découvert un bug de <em>DMA Time out</em> sur le driver <em>AHCI</em>.
<br />
Finalement, si je m'achète une carte à base de <em>STM32</em> comme <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF259090" hreflang="en">celle-là</a> ou <a href="http://www.st.com/web/en/catalog/tools/FM146/CL2167/SC2003/PF260320" title="en">celle-ci</a>.
<br />
Mais bon, y a rien de fait <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2015/06/04/A-l-abandon#rev-pnote-637-1" id="pnote-637-1">1</a>] même pas en fait</p></div>
http://frederic.praca.free.fr/index.php?post/2015/06/04/A-l-abandon#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/637Aie confiance !!!urn:md5:6c7b360475e624d9d659e134759302472014-05-16T14:39:00+02:002014-05-16T14:54:05+02:00FredDéveloppementPython<p>Bon sang !! Une année s'est écoulée depuis ma dernière publication !!<br />
Le temps passe vraiment super vite quand on s'amuse <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
<br />
En parlant d'amusement, ma dernière occupation informatique professionnelle un peu nouvelle, c'est la maintenance d'une application <a href="https://fr.wikipedia.org/wiki/Python_%28langage%29" hreflang="fr" title="Python">Python</a>.<br />
Depuis le temps que je parlais de m'y mettre sérieusement... Enfin, si tant est que faire du Python soit une activité sérieuse :D<br /></p> <p>J'ai donc récupéré une <q>petite</q> application relativement objet qui inclue :</p>
<ul>
<li>du <a href="http://pygtk.org/" hreflang="en" title="PyGtk">PyGtk</a> pour l'interface graphique,</li>
<li>des <em><a href="http://fr.wikipedia.org/wiki/Thread_%28informatique%29" hreflang="fr" title="Thread">threads</a></em>,</li>
<li>des appels <a href="http://en.wikipedia.org/wiki/%C3%98MQ" hreflang="en" title="ZMQ">ZMQ</a> via <a href="http://zeromq.github.io/pyzmq/" hreflang="en" title="PyZMQ">PyZMQ</a>,</li>
<li>et des accès à une base de données PostgreSQL via <a href="http://fr.wikipedia.org/wiki/SQLAlchemy" hreflang="fr" title="SQLAlchemy">SQLAlchemy</a></li>
</ul>
<p>Pfiouu !! tout ça pour mon premier projet en Python, c'est la classe.<br />
<br />
Je peux donc maintenant critiquer facilement ce langage <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /><br />
<br />
Mais commençons d'abord par être gentil.<br />
Finalement, coder en Python a un petit côté agréable que je comparerais aisément au plaisir du développement des petits scripts en Shell.<br />
Autre avantage du langage, la foule de bibliothèques pour faire tout et n'importe quoi, ce qui n'existe pas en Shell.<br />
Puisque je suis gentil, j'ajouterai aussi l'orientation objet du langage<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-1" id="rev-pnote-636-1">1</a>]</sup>.<br />
Enfin, parce qu'il faut bien s'arrêter un jour dans les compliments, la syntaxe n'est pas étrangère pour les vieux cons comme moi qui ont commencé en C<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-2" id="rev-pnote-636-2">2</a>]</sup>.<br />
<br />
Bon, ça suffit de sourire béatement sur la beauté du Python.<br />
Le Python, c'est un serpent. En plus, ce n'est pas un serpent spécialement inoffensif quand on est une souris.<br />
Par contre, les insectes<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-3" id="rev-pnote-636-3">3</a>]</sup> ne sont pas dans son régime alimentaire.<br />
Et bien, voilà, après avoir commencé à apprivoiser le serpent, je me suis rendu compte de plusieurs choses:</p>
<ul>
<li>il est insondable.</li>
<li>il est imprévisible. Il faut vraiment attendre le dernier moment pour savoir ce qu'il va faire.</li>
<li>il faut une patience d'ange pour s'en occuper</li>
</ul>
<p>Premier point, l'insondabilité du bidule.<br />
Je m'explique pour ceux qui n'auraient pas suivi. Je ne suis pas l'auteur du programme dont j'ai maintenant la garde.<br />
Jusqu'à il y a peu, j'étais assez tranquille, pas de remontée de bugs donc pas de correction à faire. Mais il y a quelques semaines, une petite dizaine de bugs et demandes d'évolutions me sont tombées dessus<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-4" id="rev-pnote-636-4">4</a>]</sup>.<br />
L'auteur initial ayant commis ce forfait étant parti<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-5" id="rev-pnote-636-5">5</a>]</sup>, j'ai donc dû me baser sur la transmission de savoir faite il y a maintenant 4 mois.<br />
Franchement, retomber dans un code Python de plusieurs milliers de lignes, c'est pas facile.<br />
Bien que le code soit assez bien architecturé, l'absence de types reste, pour moi, un énorme problème. En effet, dans ce cas, seul le nom de variable permet de savoir de quoi on parle.<br />
Exemple :</p>
<pre class="python python" style="font-family:inherit"><span style="color: #ff7700;font-weight:bold;">def</span> startEditContent<span style="color: black;">(</span><span style="color: #008000;">self</span>, side, order, step<span style="color: black;">)</span></pre>
<p>Alors ? <em>Side</em>, c'est quoi ? Il y a bien une énumération, enfin, une classe qui parle de ça mais est-ce bien ça ?<br />
Pour <em>Order</em>, là, pas de bol, il n'y a rien donc ça doit être un truc atomique genre entier.<br />
<br />
Au final, il n'y a pas 36 techniques, il faut retrouver tous les appels à cette méthode pour voir comment elle est appelée.<br />
Là, on se dit que l'on va être aidé par son <a href="https://fr.wikipedia.org/wiki/Environnement_de_d%C3%A9veloppement" hreflang="fr" title="IDE">IDE</a>, dans mon cas <a href="http://pydev.org/" hreflang="en" title="PyDev">PyDev</a> sous Eclipse.<br />
En fait, oui mais non. Enfin, moi, j'ai pas trop réussi et hormis faire une recherche plein texte, je n'ai pas trouvé de moyen d'afficher la hiérarchie des appels d'une fonction.<br />
Par contre, dans l'autre sens, ça a l'air de fonctionner. Conclusion je dois pas être doué.<br />
<br />
Deuxième point, l'imprévisibilité.<br />
Là, je vais être beaucoup plus rapide.<br />
Une fois que l'on a compris plus ou moins ce que c'est censé faire, après de longues heures d'analyse et de rétro-ingéniérie<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-6" id="rev-pnote-636-6">6</a>]</sup>, on tente sa première modification, la sueur perlant sur les tempes.<br />
Et là, très content, on tente le lancement de l'appli. Comme rien n'est compilé, il faut attendre patiemment de tomber dans le cas où on va passer par le code subtilement développé.<br />
Quand la ou les fameuses lignes arrivent, on croise les doigts pour ne pas avoir fait de faute de frappe sous peine de voir arriver une belle <q>traceback</q> vous annonçant que l'objet sur lequel vous tentez l'opération <em>actionne</em><sup>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#pnote-636-7" id="rev-pnote-636-7">7</a>]</sup> ne supporte en rien cet appel.<br />
Bon, ben, c'est pas grave, on recommence et on reteste.<br />
<br />
Cela m'amène justement au troisième point, la patience.<br />
Tout comme on parle souvent de la zenitude des développeurs Ruby (cf. <a href="http://frederic.praca.free.fr/index.php?post/2012/11/20/Ruby-sur-l-ongle" hreflang="en" title="Ruby">là</a>), je me dis qu'il faut aussi être très zen en Python.<br />
En effet, relancer son application sans cesse pour vérifier que le bug est bien corrigé, sans être sûr qu'il ne va pas y avoir toute une quantité de bugs que l'on pourrait éviter par une analyse de types, tient plus de l'acharnement que du génie logiciel.<br />
Alors, oui, on pourra me dire qu'il faut faire des tests unitaires dans tous les sens pour se blinder et éviter les problèmes mais comment on fait quand ça tire un modèle objet long comme un jour sans vin ?<br />
Des <q><a href="http://fr.wikipedia.org/wiki/Mock_%28programmation_orient%C3%A9e_objet%29" hreflang="fr" title="Mock">mocks</a></q> ? Dans mon cas, c'est trop compliqué.<br />
<br />
En conclusion, si Python peut être intéressant, c'est, à mon humble avis, pour de petits développements ne nécessitant pas énormément de maintenance ou pour les gros développements où le développeur est enchaîné au PC :D</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-1" id="pnote-636-1">1</a>] Attention, je ne parle pas encore de l'implémentation de l'orientation sus-nommée</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-2" id="pnote-636-2">2</a>] Bien que j'ai réellement commencé en <a href="http://fr.wikipedia.org/wiki/BASIC" hreflang="fr" title="Basic">Basic</a> 128 de Microsoft sur mon <a href="http://fr.wikipedia.org/wiki/Thomson_TO9" hreflang="fr" title="TO9">TO9</a> puis continué avec le <a href="http://fr.wikipedia.org/wiki/Pascal_%28langage%29" hreflang="fr" title="Pascal">Pascal</a> en cours d'info <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-3" id="pnote-636-3">3</a>] ou <q>bug</q> en anglais pour ceux qui ne verraient pas où je veux en venir...</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-4" id="pnote-636-4">4</a>] Au mauvais moment mais ça, c'est comme d'habitude :D</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-5" id="pnote-636-5">5</a>] C'est beau la vie de sous-traitant <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-6" id="pnote-636-6">6</a>] lire : <q>se taper tout la lecture du code à la mano</q></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#rev-pnote-636-7" id="pnote-636-7">7</a>] Par exemple, hein ?! Je vais vous montrer tout le code magnifique que je fais au boulot non plus !</p></div>
http://frederic.praca.free.fr/index.php?post/2014/05/16/Aie-confiance-%21%21%21#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/636Balancing bullshitsurn:md5:082ace6564093731481152110606184d2013-04-19T14:22:00+02:002017-03-06T15:56:21+01:00FredDéveloppementAdaCORBAJava<p>After <a href="http://frederic.praca.free.fr/index.php?post/2013/03/24/Spreading-bullshits">spreading bullshits</a>, our <em>Bullshit Company</em> has been overflown by bullshit requests.<br />
It's time to provide a bigger architecture than the one we used. Let's balance the <a href="http://cbsg.sourceforge.net/cgi-bin/live" hreflang="en" title="Bullshit Generator">Bullshit Generator</a>.<br />
<br />
For the impatients, this post will deal with several problems that a beginner could encounter or fear : <em>exceptions handling</em> and <em>sequences</em></p> <p>After dealing with millions of requests, our <em>CBSG</em> server was unable to answer to all of these.<br />
A solution is to provide a <a href="http://en.wikipedia.org/wiki/Load_balancing_%28computing%29" hreflang="en">load balancing</a> <em>CBSG</em>.<br />
To do this, we planned to dispatch several <em>CBSG</em> servants on different machines. These servants will have to register themselves to a <em>CBSGBalancer</em>.<br />
<br />
Let's start with <em>IDL</em>.<br />
We add the following at the end of our previous file:</p>
<pre class="cpp cpp" style="font-family:inherit"><span style="color: #666666;">// This exception is thrown when a client is asking for a CBSG</span>
<span style="color: #666666;">//And no more are available</span>
exception NoMoreCBSGAvailable
<span style="color: #008000;">{</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//This exception is thrown when a servant tries to unregister</span>
<span style="color: #666666;">//itself and that a client still uses it</span>
exception CBSGInUse
<span style="color: #008000;">{</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">typedef</span> sequence<span style="color: #000080;"><</span>CBSG<span style="color: #000080;">></span> CBSGSeq<span style="color: #008080;">;</span>
<span style="color: #666666;">//Our load-balancing object</span>
interface CBSGBalancer<span style="color: #008000;">{</span>
<span style="color: #666666;">//This method allows to register a new servant to put in the balancer</span>
<span style="color: #0000ff;">void</span> <span style="color: #0000ff;">register</span><span style="color: #008000;">(</span>in CBSG newServant<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//This method should be called when a servant is shut down</span>
<span style="color: #0000ff;">void</span> unregister<span style="color: #008000;">(</span>in CBSG servantToRemove<span style="color: #008000;">)</span> raises <span style="color: #008000;">(</span>CBSGInUse<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//This method is for client wanting to use a CBSG</span>
CBSG reserve<span style="color: #008000;">(</span><span style="color: #008000;">)</span> raises <span style="color: #008000;">(</span>NoMoreCBSGAvailable<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//This method allows a client to reserve several CBSG</span>
<span style="color: #666666;">//Less than the parameter could be returned depending on the number available</span>
<span style="color: #666666;">//The exception is thrown when none can be returned</span>
CBSGSeq reserveSeveral<span style="color: #008000;">(</span>in <span style="color: #0000ff;">long</span> numberToReserve<span style="color: #008000;">)</span> raises <span style="color: #008000;">(</span>NoMoreCBSGAvailable<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//This method must be called by client to </span>
<span style="color: #666666;">//release a previously reserved CBSG</span>
<span style="color: #0000ff;">void</span> release<span style="color: #008000;">(</span>in CBSG noMoreUsedCBSG<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span></pre>
<p>The IDL code is self-explanatory and reflects what we described before.<br />
Take care of keeping your last <em>*-impl.ad[sb]</em> as the generation will overwrite them<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#pnote-635-1" id="rev-pnote-635-1">1</a>]</sup>.<br />
We generate Ada code from it like in the previous post:</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ iac -i ../idl/cbsg.idl
</pre>
<p><br />
Ok, now, we have to write the code of our balancer.<br />
<br /></p>
<h2>The Balancer</h2>
<p>First of all, let's modify the spec :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #adadad; font-style: italic;">--[snip...]</span>
<span style="color: #46aa03; font-weight:bold;">function</span> <span style="color: #7f007f;">"="</span> <span style="color: #66cc66;">(</span>Left, Right : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">return</span> Boolean;
<span style="color: #46aa03; font-weight:bold;">private</span>
<span style="color: #46aa03; font-weight:bold;">package</span> Ref_Vectors <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Containers</span>.<span style="color: #202020;">Vectors</span><span style="color: #66cc66;">(</span>Index_Type => Positive,
Element_Type => CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span>
<span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">type</span> Object <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">new</span> PortableServer.<span style="color: #202020;">Servant_Base</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">record</span>
Usable_Refs : Ref_Vectors.<span style="color: #202020;">Vector</span>;
In_Use_Refs : Ref_Vectors.<span style="color: #202020;">Vector</span>;
<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;
<span style="color: #adadad; font-style: italic;">--[snip...]</span></pre>
<p>We will use a standard Ada <a href="http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-18-2.html" hreflang="en">Vector</a> to keep our <em>CBSG</em> servants. As a consequence, we need a way to test equality on <em>CBSG</em> references.<br />
As you can see, we use two vectors for this. This is easy, one for available servants and the other for busy ones.<br />
Now, here's the implementation. First, the <em>register</em> method :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">procedure</span> register
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object;
newServant : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span><span style="color: #66cc66;">)</span>
<span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
Ref_Vectors.<span style="color: #202020;">Append</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">Usable_Refs</span>, NewServant<span style="color: #66cc66;">)</span>;
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"A servant was registered"</span><span style="color: #66cc66;">)</span>;
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"It corbaloc is "</span> & To_Standard_String<span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span><span style="color: #66cc66;">(</span>NewServant<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span> register;</pre>
<p>In fact, we will not receive <em>CBSG</em> servants directly but references to them<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#pnote-635-2" id="rev-pnote-635-2">2</a>]</sup>.<br />
We simply add the reference to our vector.<br />
As in every quick and dirty code, we use standard output for logging :D<br />
Off course, using <a href="http://www.codelabs.ch/alog/" hreflang="en">Alog</a>, <a href="http://libre.adacore.com/tools/gnat-component-collection/" hreflang="en">GNATCOLL</a> or <em>whatever</em> logging framework would be smarter.<br />
After registering, we need unregistering</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">procedure</span> unregister
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object;
servantToRemove : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span><span style="color: #66cc66;">)</span>
<span style="color: #00007f;">is</span>
Index : Ref_Vectors.<span style="color: #202020;">Cursor</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- first, test if present in usable</span>
index := Ref_Vectors.<span style="color: #202020;">Find</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">Usable_Refs</span>, ServantToRemove<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">if</span> <span style="color: #66cc66;">(</span>Index /= Ref_Vectors.<span style="color: #202020;">No_Element</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Ref_Vectors.<span style="color: #202020;">Delete</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">Usable_Refs</span>, Index<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">else</span>
<span style="color: #46aa03; font-weight:bold;">raise</span> CBSGInUse;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #00007f;">end</span> unregister;</pre>
<p>We simply remove from the vector where it's referenced... Well, this could be better as we can imagine that the servant which is unregistering would probably quit anyway but reliability is not part of this post <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
As you could have seen exceptions in CORBA are just plain old Ada exceptions. That's all !!!<br />
<br /></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">function</span> reserve
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object<span style="color: #66cc66;">)</span>
<span style="color: #00007f;">return</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span>
<span style="color: #00007f;">is</span>
First_Cursor : Ref_Vectors.<span style="color: #202020;">Cursor</span> := Ref_Vectors.<span style="color: #202020;">First</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">Usable_Refs</span><span style="color: #66cc66;">)</span>;
Returned_Ref : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">if</span> <span style="color: #66cc66;">(</span>First_Cursor /= Ref_Vectors.<span style="color: #202020;">No_Element</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Returned_ref := Ref_Vectors.<span style="color: #202020;">Element</span><span style="color: #66cc66;">(</span>First_Cursor<span style="color: #66cc66;">)</span>;
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"Sending "</span> & To_Standard_String<span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span><span style="color: #66cc66;">(</span>Returned_Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- we put it in use</span>
Ref_Vectors.<span style="color: #202020;">Append</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">In_Use_Refs</span>, Ref_Vectors.<span style="color: #202020;">Element</span><span style="color: #66cc66;">(</span>First_Cursor<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- we remove it from usable</span>
Ref_Vectors.<span style="color: #202020;">Delete</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">Usable_Refs</span>, First_Cursor<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">else</span>
<span style="color: #46aa03; font-weight:bold;">raise</span> NoMoreCBSGAvailable;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #00007f;">return</span> Returned_Ref;
<span style="color: #00007f;">end</span> reserve;</pre>
<p>Now what about sequences we use in <em>reserveSeveral</em>?<br />
Well, it's more complicated than in other languages but let's check.<br />
In our case as sequence is a <em>typedef</em> in our package, the specification is in <em>corbacbsg.ads</em></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #adadad; font-style: italic;">--snip</span>
<span style="color: #46aa03; font-weight:bold;">package</span> CBSG_Forward <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">new</span> CORBA.<span style="color: #202020;">Forward</span>;
<span style="color: #adadad; font-style: italic;">--snip</span>
<span style="color: #46aa03; font-weight:bold;">package</span> IDL_SEQUENCE_CorbaCBSG_CBSG_Forward <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">new</span> CORBA.<span style="color: #202020;">Sequences</span>.<span style="color: #202020;">Unbounded</span>
<span style="color: #66cc66;">(</span>CorbaCBSG.<span style="color: #202020;">CBSG_Forward</span>.<span style="color: #202020;">Ref</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">type</span> CBSGSeq <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">new</span> CorbaCBSG.<span style="color: #202020;">IDL_SEQUENCE_CorbaCBSG_CBSG_Forward</span>.<span style="color: #202020;">Sequence</span>;
<span style="color: #adadad; font-style: italic;">--snip</span></pre>
<p>In fact, in PolyORB, <em>sequences</em> don't contain directly our object but an adapter object called <em>Forward</em> as explain on <a href="http://kothar.net/blog/brief-introduction-to-polyorb.html" hreflang="en">Khotar Labs blog</a>. So we won't be able to return a reference array but an array of forward objects containing references.<br />
As sequences are instanciations of <em>CORBA.Sequences.Unbounded</em> generic package which in fact are <em>PolyORB.Sequences.Unbounded</em>, all we need is in the <em>polyorb-sequences-unbounded.ads</em> file.<br /></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #adadad; font-style: italic;">--snip</span>
<span style="color: #46aa03; font-weight:bold;">function</span> reserveSeveral
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object;
NumberToReserve : CORBA.<span style="color: #202020;">Long</span><span style="color: #66cc66;">)</span>
<span style="color: #00007f;">return</span> CorbaCBSG.<span style="color: #202020;">CBSGSeq</span>
<span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">use</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Convert_Forward</span>;
Returned_Seq : CorbaCBSG.<span style="color: #202020;">CBSGSeq</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">for</span> Index <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #ff0000;">1</span>..<span style="color: #202020;">NumberToReserve</span> <span style="color: #00007f;">loop</span>
<span style="color: #00007f;">begin</span>
Append<span style="color: #66cc66;">(</span>Returned_Seq,
To_Forward<span style="color: #66cc66;">(</span>
Reserve<span style="color: #66cc66;">(</span>Self<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> NoMoreCBSGAvailable =>
<span style="color: #00007f;">if</span> <span style="color: #66cc66;">(</span>Index = <span style="color: #ff0000;">1</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
<span style="color: #46aa03; font-weight:bold;">raise</span>;
<span style="color: #00007f;">else</span>
<span style="color: #46aa03; font-weight:bold;">exit</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">loop</span>;
<span style="color: #00007f;">return</span> Returned_Seq;
<span style="color: #00007f;">end</span> reserveSeveral;
<span style="color: #adadad; font-style: italic;">--snip</span></pre>
<p>In order to convert our objects into <em>forward</em> objects, we need to use the <em>To_Forward</em> function. This function is defined as a package called <em>Convert_Forward</em> in the file representing the object to store. In our case, it will be in <em>CorbaCBSG-cbsg.ads</em>.<br />
Once the object has been converted, we can put it in our sequence using <em>Append</em>... Easy <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
Well, this implementation is not really great as it can return fewer references than requested but it conforms to our spec in the IDL file <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /><br />
<br />
Finally, the <em>release</em> function is quite simple.<br /></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">procedure</span> release
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object;
noMoreUsedCBSG : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span><span style="color: #66cc66;">)</span>
<span style="color: #00007f;">is</span>
In_Use_Cursor : Ref_Vectors.<span style="color: #202020;">Cursor</span> := Ref_Vectors.<span style="color: #202020;">Find</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">In_Use_Refs</span>, noMoreUsedCBSG<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- we remove it from in use vector if present</span>
<span style="color: #00007f;">if</span> <span style="color: #66cc66;">(</span>In_Use_Cursor /= Ref_Vectors.<span style="color: #202020;">No_Element</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Ref_Vectors.<span style="color: #202020;">Delete</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">In_Use_Refs</span>, In_Use_Cursor<span style="color: #66cc66;">)</span>;
Ref_Vectors.<span style="color: #202020;">Append</span><span style="color: #66cc66;">(</span>Self.<span style="color: #202020;">Usable_Refs</span>, NoMoreUsedCBSG<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #00007f;">end</span> release;</pre>
<p><br />
The last function to implement is the equality for our objects. As <em>Corbaloc</em> are unique, the test only deals with this :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">function</span> <span style="color: #7f007f;">"="</span> <span style="color: #66cc66;">(</span>Left, Right : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">return</span> Boolean
<span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">if</span> <span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span><span style="color: #66cc66;">(</span>left<span style="color: #66cc66;">)</span> = PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span><span style="color: #66cc66;">(</span>right<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
<span style="color: #00007f;">return</span> True;
<span style="color: #00007f;">else</span>
<span style="color: #00007f;">return</span> False;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #00007f;">end</span> <span style="color: #7f007f;">"="</span>;</pre>
<p><br />
Our servant is implemented, so it's time to expose it :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Exceptions</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Object</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POAManager</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>;
<span style="color: #adadad; font-style: italic;">-- allows to specify to PolyORB how to run</span>
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Balancer <span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- We retrieve paramaters defined in CORBA standard such a InitialRef</span>
Argv : CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Arg_List</span> := CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Command_Line_Arguments</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- We initialize our bus as ORB</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Init</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>, Argv<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- The PortableObjectAdapter is where we store our objects</span>
Root_POA : PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Local_Ref</span>;
<span style="color: #adadad; font-style: italic;">-- we declare a reference on it</span>
Ref : CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #adadad; font-style: italic;">-- and its implementation</span>
Obj : <span style="color: #46aa03; font-weight:bold;">constant</span> CORBA.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object_Ptr</span> := <span style="color: #46aa03; font-weight:bold;">new</span> CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Get the root POA</span>
Root_POA := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>.<span style="color: #202020;">To_Local_Ref</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Resolve_Initial_References</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"RootPOA"</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Start it</span>
PortableServer.<span style="color: #202020;">POAManager</span>.<span style="color: #202020;">Activate</span>
<span style="color: #66cc66;">(</span>PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Get_The_POAManager</span> <span style="color: #66cc66;">(</span>Root_POA<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Create a reference in the POA</span>
Ref := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Servant_To_Reference</span>
<span style="color: #66cc66;">(</span>Root_POA, PortableServer.<span style="color: #202020;">Servant</span> <span style="color: #66cc66;">(</span>Obj<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Display the IOR</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Object_To_String</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
New_Line;
<span style="color: #adadad; font-style: italic;">-- and the corbaloc</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span>
<span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Launch the server. CORBA.ORB.Run is supposed to never return,</span>
<span style="color: #adadad; font-style: italic;">-- print a message if it does.</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Run</span>;
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB main loop terminated!"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> E : <span style="color: #46aa03; font-weight:bold;">others</span> =>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"CBSG Balancer server raised "</span> & Ada.<span style="color: #202020;">Exceptions</span>.<span style="color: #202020;">Exception_Information</span> <span style="color: #66cc66;">(</span>E<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">raise</span>;
<span style="color: #00007f;">end</span> Balancer;</pre>
<p>There's nothing special to say about it, so we go on with the <em>CBSG</em> that will register to the <em>balancer</em>
<br /></p>
<h2>The registering <em>CBSG</em></h2>
<p>In fact, our previously implemented <em>CBSG</em> is still usable without any modification. The only thing we have to do is to change the way we launch it.<br />
This time, we will also need a reference to the balancer and we will need to register it.<br />
The code is really simple.</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Command_Line</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Command_Line</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Exceptions</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Object</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POAManager</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Helper</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>;
<span style="color: #adadad; font-style: italic;">-- Specify to PolyORB how to dea with tasks</span>
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Registering_Servant <span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- Allows to get parameters as defined in Corba standard like InitialRef</span>
Argv : CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Arg_List</span> := CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Command_Line_Arguments</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Init our bus under ORB name</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Init</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>, Argv<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- PortableObjectAdapter is where we store our objects</span>
Root_POA : PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Local_Ref</span>;
<span style="color: #adadad; font-style: italic;">-- We declare a reference for our object</span>
Ref : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #adadad; font-style: italic;">-- and its implementation</span>
Obj : <span style="color: #46aa03; font-weight:bold;">constant</span> CORBA.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object_Ptr</span> := <span style="color: #46aa03; font-weight:bold;">new</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object</span>;
<span style="color: #adadad; font-style: italic;">-- we declare a reference to the balancer</span>
Balancer : CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #00007f;">begin</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Initialize</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">if</span> Argument_Count <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">2</span> <span style="color: #00007f;">then</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"usage: registered_servant <IOR_string_from_server>"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #adadad; font-style: italic;">-- Get a reference on the distributed object through its IOR or corbaloc</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">String_To_Object</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span>Ada.<span style="color: #202020;">Command_Line</span>.<span style="color: #202020;">Argument</span> <span style="color: #66cc66;">(</span><span style="color: #ff0000;">1</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>, Balancer<span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Check the reference is correct</span>
<span style="color: #00007f;">if</span> CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Is_Nil</span><span style="color: #66cc66;">(</span>Balancer<span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"main : cannot invoke on a nil reference"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #adadad; font-style: italic;">-- Get the root</span>
Root_POA := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>.<span style="color: #202020;">To_Local_Ref</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Resolve_Initial_References</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"RootPOA"</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Start our POA</span>
PortableServer.<span style="color: #202020;">POAManager</span>.<span style="color: #202020;">Activate</span>
<span style="color: #66cc66;">(</span>PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Get_The_POAManager</span> <span style="color: #66cc66;">(</span>Root_POA<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- We create a ref to expose it</span>
Ref := CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Helper</span>.<span style="color: #202020;">To_Ref</span><span style="color: #66cc66;">(</span>PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Servant_To_Reference</span>
<span style="color: #66cc66;">(</span>Root_POA, PortableServer.<span style="color: #202020;">Servant</span> <span style="color: #66cc66;">(</span>Obj<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- we display the IOR</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Object_To_String</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
New_Line;
<span style="color: #adadad; font-style: italic;">-- and the CorbaLoc</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span>
<span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Ask to register to the balancer</span>
CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Register</span><span style="color: #66cc66;">(</span>Balancer, Ref<span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Launch the server. CORBA.ORB.Run is supposed to never return,</span>
<span style="color: #adadad; font-style: italic;">-- print a message if it does.</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Run</span>;
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB main loop terminated!"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> E : <span style="color: #46aa03; font-weight:bold;">others</span> =>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"CBSG server raised "</span> & Ada.<span style="color: #202020;">Exceptions</span>.<span style="color: #202020;">Exception_Information</span> <span style="color: #66cc66;">(</span>E<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">raise</span>;
<span style="color: #00007f;">end</span> Registering_Servant;</pre>
<p>In this code, we launch our server with a parameter which is the <em>IOR</em> of our <em>balancer</em>. This parameter allows to get a reference on it in order to call the <em>register</em> function.<br />
That's all for it.<br /></p>
<h2>Our Java client</h2>
<p>This time, we will use a <em>Java</em> client to request bullshits.<br /></p>
<pre class="java java" style="font-family:inherit"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.omg.CORBA.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">CorbaCBSG.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CBSGClient
<span style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">(</span><span style="color: #003399;">String</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> argv<span style="color: #009900;">)</span>
<span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">//First, init the ORB</span>
<span style="color: #003399;">ORB</span> orb <span style="color: #339933;">=</span> <span style="color: #003399;">ORB</span>.<span style="color: #006633;">init</span><span style="color: #009900;">(</span>argv, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
org.<span style="color: #006633;">omg</span>.<span style="color: #006633;">CORBA</span>.<span style="color: #003399;">Object</span> obj <span style="color: #339933;">=</span> orb.<span style="color: #006633;">string_to_object</span><span style="color: #009900;">(</span>argv<span style="color: #009900;">[</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
CBSGBalancer cbsgBalancer <span style="color: #339933;">=</span> CBSGBalancerHelper.<span style="color: #006633;">narrow</span><span style="color: #009900;">(</span>obj<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">try</span>
<span style="color: #009900;">{</span>
CBSG<span style="color: #009900;">[</span><span style="color: #009900;">]</span> cbsgArray <span style="color: #339933;">=</span> cbsgBalancer.<span style="color: #006633;">reserveSeveral</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;"><</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">)</span>
<span style="color: #009900;">{</span>
<span style="color: #003399;">String</span> returned_l <span style="color: #339933;">=</span> cbsgArray<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span>.<span style="color: #006633;">createSentence</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"The generator "</span> <span style="color: #339933;">+</span> i <span style="color: #339933;">+</span> <span style="color: #0000ff;">" said : "</span> <span style="color: #339933;">+</span> returned_l<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// We release it</span>
cbsgBalancer.<span style="color: #006633;">release</span><span style="color: #009900;">(</span>cbsgArray<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">(</span>NoMoreCBSGAvailable ex<span style="color: #009900;">)</span>
<span style="color: #009900;">{</span>
<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Ouch !! We can't reserve one CBSG"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<p>Simple !!<br />
I won't describe here how <em>Java</em> deals with <em>Corba</em> through <em>helpers</em>, <em>Operations</em>' classes.<br />
Ok, I forgot one thing and you could say :</p>
<blockquote><p>What about using sequences in <em>Ada</em> ?</p></blockquote>
<p>Ok, we will implement a client in <em>Ada</em> to show it <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br /></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Command_Line</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Command_Line</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">Procedure</span> Balanced_Client <span style="color: #00007f;">is</span>
Argv : CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Arg_List</span> := CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Command_Line_Arguments</span>;
<span style="color: #adadad; font-style: italic;">-- We declare a reference to the balancer</span>
Balancer : CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #adadad; font-style: italic;">-- The sequence of CBSG to call</span>
Callees : CorbaCBSG.<span style="color: #202020;">CBSGSeq</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Init the ORB</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Init</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>, Argv<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">if</span> Argument_Count <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">2</span> <span style="color: #00007f;">then</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"usage: balanced_client <IOR_string_from_server>"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #adadad; font-style: italic;">-- Get our balancer through its corbaloc or IOR</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">String_To_Object</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span>Ada.<span style="color: #202020;">Command_Line</span>.<span style="color: #202020;">Argument</span> <span style="color: #66cc66;">(</span><span style="color: #ff0000;">1</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>, Balancer<span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Check it's correct</span>
<span style="color: #00007f;">if</span> CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Is_Nil</span><span style="color: #66cc66;">(</span>Balancer<span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"main : cannot invoke on a nil reference"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #adadad; font-style: italic;">-- Ask several CBSG to the balancer</span>
Callees := CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">ReserveSeveral</span><span style="color: #66cc66;">(</span>Balancer, <span style="color: #ff0000;">2</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Call each one</span>
<span style="color: #00007f;">for</span> Index <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #ff0000;">1</span>..<span style="color: #202020;">CorbaCBSG</span>.<span style="color: #202020;">Length</span><span style="color: #66cc66;">(</span>Callees<span style="color: #66cc66;">)</span> <span style="color: #00007f;">loop</span>
<span style="color: #00007f;">declare</span>
The_Cbsg : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span> :=
CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Convert_Forward</span>
.<span style="color: #202020;">From_Forward</span><span style="color: #66cc66;">(</span>
CorbaCBSG.<span style="color: #202020;">Get_Element</span><span style="color: #66cc66;">(</span>Callees, Index<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Call the element</span>
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"The generator "</span> & Positive'Image<span style="color: #66cc66;">(</span>Index<span style="color: #66cc66;">)</span> & <span style="color: #7f007f;">" said : "</span> & Corba.<span style="color: #202020;">To_Standard_String</span><span style="color: #66cc66;">(</span>The_Cbsg.<span style="color: #202020;">createSentence</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
CorbaCBSG.<span style="color: #202020;">CBSGBalancer</span>.<span style="color: #202020;">Release</span><span style="color: #66cc66;">(</span>Balancer, The_Cbsg<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">loop</span>;
<span style="color: #00007f;">end</span> Balanced_Client;</pre>
<p>The most difficult part is the last one... But, it's not that diffcult.<br />
You just have to remember that :</p>
<ol>
<li>Our sequence was declared inside the top-level part of the IDL</li>
<li>Our sequence contains <em>forward</em> objects instead of reference directly</li>
</ol>
<p>So, for the first point, all methods declared for sequences<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#pnote-635-3" id="rev-pnote-635-3">3</a>]</sup> are available in our top-level package.<br />
For the second point, we will have to convert our <em>forward</em> objects to the ones we really want. This will be done with <em>From_Forward</em> function in the <em>Convert_Forward</em> package. As this conversion package deals with objects, it is declared in the object package and not at the top-level.<br />
<br />
We now have a <em>balancer</em>, a <em>CBSG</em> able to register itself to the <em>balancer</em> and two clients.<br />
It should work <em>out-of-the-box</em> if you run the programs on the same machine but if you want to run it across several machines<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#pnote-635-4" id="rev-pnote-635-4">4</a>]</sup>, you will have to use <em>InitialRef</em> or equivalent parameters.<br />
I can't be more precise as, even if I tested it, I've lost the configuration I used :D<br />
Maybe, I'll update this post to provide you the correct parameters. Stay tuned <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /><br /></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#rev-pnote-635-1" id="pnote-635-1">1</a>] Something I just forgot few minutes ago :D</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#rev-pnote-635-2" id="pnote-635-2">2</a>] Using ValueType would be a different thing but it is not currently implemented in <em>PolyORB</em></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#rev-pnote-635-3" id="pnote-635-3">3</a>] in <em>PolyORB.Sequences.Unbounded</em> through <em>Corba.Sequences.Unbounded</em></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#rev-pnote-635-4" id="pnote-635-4">4</a>] Which must be the goal of such architecture <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /></p></div>
http://frederic.praca.free.fr/index.php?post/2013/04/19/Balancing-bullshits#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/635I've got the power (english version)urn:md5:d98ef59c72786cea72a7f8d473dd106c2013-04-02T10:47:00+02:002013-04-02T09:50:49+02:00FredSystème et réseauFreeBSD<p>This is a translation of an old post in french, see the original <a href="http://frederic.praca.free.fr/index.php?post/2011/03/28/I-ve-got-the-power-%21%21">here</a>.<br />
<br />
No, I've not become <em>Fred Almighty</em> and that's happy, it would be a mess :D
<br />
In the scope of non-profit activities, I received a wonderful UPS that I had to configure for FreeBSD.<br /></p> <p>At the beginnning, to be honest, I was not really motivated to configure this beast for the Wonderful OS especially after seeing that all different tools where in Java<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/02/I-ve-got-the-power-%28english-version%29#pnote-634-1" id="rev-pnote-634-1">1</a>]</sup>.<br />
After having my server configured to access it from home<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/02/I-ve-got-the-power-%28english-version%29#pnote-634-2" id="rev-pnote-634-2">2</a>]</sup> and plugged to the UPS through the USB cable, I've been looking for a way to make it work.<br />
A small query on Internet and I have found a small load monitor running of FreeBSD named <a href="http://www.networkupstools.org/index.html" hreflang="en">Nut</a> which is hosted by <a href="http://powerquality.eaton.com/USA/Default.asp?CX=3" hreflang="en">Eaton</a>... This seems to be good while your UPS is a <em>Eaton Ellipse ASR750</em> <img src="/themes/default/smilies/wink.png" alt=";-)" class="smiley" />
<br /></p>
<p>A quick tour of supported hardware is a piece of cake and confirms that everything will be alright.<br />
So, I install <em>Nut</em> through the classical way :</p>
<pre>
root@rcjserveur : ~> cd /usr/ports/sysutils/nut/ && make install clean
</pre>
<p>Configuration is not so hard even if I have to change few points like compared to <a href="http://people.freebsd.org/~thierry/nut_FreeBSD_HowTo.txt" hreflang="en">this</a> :<br />
For <em>ups.conf</em>, keep it simple :</p>
<pre>
[eaton]
driver = usbhid-ups
port = auto
desc = "EATON UPS"
</pre>
<p><br /></p>
<p><em>hosts.conf</em></p>
<pre>
#
MONITOR eaton@localhost "UPS Eaton Ellipse"
# MONITOR su2200@10.64.1.1 "Finance department"
# MONITOR matrix@shs-server.example.edu "Sierra High School data room #1"
</pre>
<p><br />
For <em>upsd.users</em></p>
<pre>
Sorry, I won't give you this one, there are some credentials in it !!!
</pre>
<p><br />
In <em>upsmon.conf</em></p>
<pre>
...
MONITOR eaton@localhost 1 my_user my_password master
...
SHUTDOWNCMD "/sbin/shutdown -p +0"
</pre>
<p><br />
Everything seemed to be ok but...<br />
The main problem came from the rights on the USB as usual. In fact, at login time or at startup, rights are really <q>generics</q>.<br />
Happily, FreeBSD is here to help you and give you the answer tanks to <a href="http://www.freebsd.org/cgi/man.cgi?query=devd&sektion=8&apropos=0&manpath=FreeBSD+8.2-RELEASE" hreflang="en">''devd''</a> and to its configuration curiously named <a href="http://www.freebsd.org/cgi/man.cgi?query=devd.conf&sektion=5&apropos=0&manpath=FreeBSD+8.2-RELEASE" hreflang="en">''devd.conf''</a>.
For your information, I found this solution more elegant and more generic than using <em>devfs</em>.<br /></p>
<pre>
attach 100 {
match "vendor" "0x0463";
match "product" "0xffff";
action "/usr/sbin/chown -R -L uucp:uucp /dev/$device-name";
};
</pre>
<p>Off course, these values are not randomly chosen, a quick use of <a href="http://www.freebsd.org/cgi/man.cgi?query=usbconfig&apropos=0&sektion=0&manpath=FreeBSD+8.2-RELEASE&format=html" hreflang="en">''usbconfig''</a> gives you the hints</p>
<pre>
root@rcjserveur : ~> usbconfig -u 4 -a 2 dump_device_desc
ugen4.2: <ELLIPSE EATON> at usbus4, cfg=0 md=HOST spd=LOW (1.5Mbps) pwr=ON
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0110
bDeviceClass = 0x0000
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0008
idVendor = 0x0463
idProduct = 0xffff
bcdDevice = 0x0001
iManufacturer = 0x0001 <EATON>
iProduct = 0x0002 <ELLIPSE>
iSerialNumber = 0x0004 <BDCK520CF>
bNumConfigurations = 0x0001
</pre>
<p><br />
<br />
Tests were simple too. I just checked that I could see the charge of the machine while telling myself that for a shutdown script, I'll look at it later.<br />
Well, as Murphy's law tells, it was checked by itself as there was a power outage on friday evening until monday morning. Seeking in the logs, I found the Holy Graal :</p>
<pre>
Mar 11 17:28:35 RCJServeur upsmon[32074]: UPS eaton@localhost on battery
...
Mar 11 17:42:16 RCJServeur upsmon[32074]: UPS eaton@localhost battery is low
Mar 11 17:42:16 RCJServeur upsmon[32074]: Executing automatic power-fail shutdown
Mar 11 17:42:16 RCJServeur upsmon[32074]: Auto logout and shutdown proceeding
Mar 11 17:42:21 RCJServeur shutdown: power-down by fred:
Mar 11 17:42:23 RCJServeur upsd[32047]: mainloop: Interrupted system call
</pre>
<p>Great, the server shut down correctly when the UPS was out of power. Well done Fred, you've got the power !!!<br />
What surprised me is that the server started up by itself when power came back and despite the fact that I did'nt configure anything for that <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
Well, this is not really a problem so I can sleep well :D</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/02/I-ve-got-the-power-%28english-version%29#rev-pnote-634-1" id="pnote-634-1">1</a>] I work with it all the day, so I won't play with it on my spare time also <img src="/themes/default/smilies/wink.png" alt=";-)" class="smiley" /></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/04/02/I-ve-got-the-power-%28english-version%29#rev-pnote-634-2" id="pnote-634-2">2</a>] Won't tell you how, it would be too risky, bitthirsty hackers !!</p></div>
http://frederic.praca.free.fr/index.php?post/2013/04/02/I-ve-got-the-power-%28english-version%29#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/634Spreading bullshitsurn:md5:39ed85e55315b72939f0efbcbc5751772013-03-24T22:32:00+01:002017-03-06T15:42:24+01:00FredDéveloppementAdaCCORBA<p>I decided today to write a small cute tutorial to create the best of the best for <q>scalability</q>, for <q>highly distributed</q> and <q>high reliability</q> while being multi-platform, multi-language and potentially multi-paradigm... Well, the two first ones, ok but for the last, I don't really know and finally, I don't give a damn :D<br />
At this point, with the number of <em>buzzwords</em> I used, your trollmeter should explode !! :D<br />
But, from now, I won't tell you anything else, you'll have to read what follows !!</p> <p>What would be better to do the whole thing than <em>web services</em> ?<br />
Well, it's simple, something else than <em>web service</em> <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
This other thing is an old stuff nobody wants to use anymore because it's too complicated, too heavy to set up and to code, here is <em><a href="http://en.wikipedia.org/wiki/Common_Object_Request_Broker_Architecture" hreflang="en" title="CORBA">CORBA</a></em> !!<br />
<br />
Well, after thinking about it, it's not a real <em>CORBA</em> tutorial because there are a lot on Internet but it's more a documented example for a small app done with <em><a href="http://libre.adacore.com/tools/polyorb" hreflang="en" title="PolyORB">PolyORB</a></em> for server-side and <em><a href="http://omniorb.sourceforge.net/" hreflang="en" title="OmniORB">OmniORB</a></em> for the C++ client-side.<br />
<br /></p>
<h4>The dispenser</h4>
<p>It's as good as a movie title but what are we distributing ?<br />
As I didn't want to build a whole app to distribute, I decided to use an existing application helping everyone on an almost daily basis. Here is the <em><a href="http://cbsg.sourceforge.net/cgi-bin/live" hreflang="en" title="CBSG">Corporate Bullshit Generator</a></em> from my Ada friend Gautier.<br />
For those who don't know already, this application provides excellent sentences to use in every good meeting with commercials, strategy managers and so on.<br />
Let's go on <a href="http://sourceforge.net/projects/cbsg/" hreflang="en" title="CBSG">the project page</a> in order to download the source code<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/24/Spreading-bullshits#pnote-633-1" id="rev-pnote-633-1">1</a>]</sup>.<br />
<br /></p>
<h3>Small analysis of <q>bullshits</q></h3>
<p>To do some <em>CORBA</em>, we have to know what to distribute. The central package in <em>CBSG</em> is <em>Corporate_Bullshit</em>. It's a generic package to define the end of line characters and the sentence to use to simulate a dialog<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/24/Spreading-bullshits#pnote-633-2" id="rev-pnote-633-2">2</a>]</sup>.<br />
So, what do we see ?<br /></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">function</span> Sentence <span style="color: #00007f;">return</span> String;
<span style="color: #46aa03; font-weight:bold;">function</span> Workshop <span style="color: #00007f;">return</span> String;
<span style="color: #46aa03; font-weight:bold;">function</span> Short_Workshop <span style="color: #00007f;">return</span> String;
<span style="color: #46aa03; font-weight:bold;">function</span> Financial_Report <span style="color: #00007f;">return</span> String;</pre>
<p>Four functions allowing to create a string containing the set of <q>bullshits</q>. Let's be crazy, we will provide an interface for all of them.<br />
In <em>CORBA</em>, it's quite simple, we will get the following <em><a href="http://www.omg.org/gettingstarted/omg_idl.htm" hreflang="en" title="IDL">IDL</a></em> file :</p>
<pre class="cpp cpp" style="font-family:inherit">module CorbaCBSG <span style="color: #008000;">{</span>
interface CBSG<span style="color: #008000;">{</span>
string createSentence<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
string createWorkshop<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
string createShortWorkshop<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
string createFinancialReport<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span></pre>
<p>Here, I preferred to use writing conventions in use for C++, Java and others rather than the ones used in Ada in order not to scare the coder that would prefer to write the client with one of these languages <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /><br />
Well, finally, it's piece of cake ! :D<br />
<br />
But this is only a first example...<br />
<br /></p>
<h3>Generation</h3>
<p>Let's go for the generation and implementation for server-side part.<br />
For this reason, I recommand to create a directory <em>corba</em> containing a directory <em>idl</em> and directories <em>Ada</em> and <em>C++</em>. The whole thing should be placed inside a directory <em>cbsg</em>. The file <em>cbsg.idl</em> defined will fit inside the <em>idl</em> directory.<br />
Let's make serious things :</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ iac -i ../idl/cbsg.idl
</pre>
<p>Eleven files are created. Only <em>corbacbsg-cbsg-impl.ads</em> and <em>corbacbsg-cbsg-impl.adb</em> will be interesting, the others are only <em>CORBA</em> plumbing. One important point though, the <em>i</em> option will overwrite your implementation if it exists already and also the spec if it contains specific fields.<br />
In the spec file (<em>ads</em> file), there's nothing to change. In fact, our <em>CORBA</em> object doesn't hold a specific state as the <em>CBSG</em> does.<br />
But, it's interesting to read this file as the reader will notice that generated methods does not use the standard <em>String</em> type we can find in <em>Ada</em> but a <em>CORBA</em> specific type. Our <em>CORBA</em> object will do the translation.<br />
As you're really smart, I'll only give the implementation for <em>createSentence</em> function and how to declare the generic package <em>Corporate_Bullshit</em>, you'll manage to generalize on your own :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">package</span> Simple_Generator <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Corporate_Bullshit<span style="color: #66cc66;">(</span>Paragraph => <span style="color: #7f007f;">""</span>,
Dialog_Mark => <span style="color: #7f007f;">""</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">--------------------</span>
<span style="color: #adadad; font-style: italic;">-- createSentence --</span>
<span style="color: #adadad; font-style: italic;">--------------------</span>
<span style="color: #46aa03; font-weight:bold;">function</span> createSentence
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object<span style="color: #66cc66;">)</span>
<span style="color: #00007f;">return</span> CORBA.<span style="color: #202020;">String</span>
<span style="color: #00007f;">is</span>
Generated_Sentence : String := Simple_Generator.<span style="color: #202020;">Sentence</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">return</span> CORBA.<span style="color: #202020;">To_CORBA_String</span><span style="color: #66cc66;">(</span>Generated_Sentence<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span> createSentence;</pre>
<p>Now that we've defined the behaviour of our object, it's time to statup the <em>CORBA</em> bus and expose an instance of our brand new class.<br />
For now, we won't use one of the most used <em>CORBA</em> service, the <em>Name Service</em>. Our server will only expose an <em><a href="http://en.wikipedia.org/wiki/Interoperable_Object_Reference" hreflang="en" title="IOR">IOR</a></em>, reference to our object.<br />
For this server, the <em>echo</em> example provided with <em>PolyORB</em> will be enough :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Exceptions</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Object</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POAManager</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>;
<span style="color: #adadad; font-style: italic;">-- Allow to specify to PolyORB how to behave from a tasking point of view</span>
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Server <span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- Allows to get the paramters such as those defined in the CORBA standard like InitialRef</span>
Argv : CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Arg_List</span> := CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Command_Line_Arguments</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Initiliaze our bus under the name ORB</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Init</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>, Argv<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- The PortableObjectAdapter is where we register our objects</span>
Root_POA : PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Local_Ref</span>;
<span style="color: #adadad; font-style: italic;">-- We declare a reference for our object</span>
Ref : CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #adadad; font-style: italic;">-- And its implementation</span>
Obj : <span style="color: #46aa03; font-weight:bold;">constant</span> CORBA.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object_Ptr</span> := <span style="color: #46aa03; font-weight:bold;">new</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- We get the Root POA</span>
Root_POA := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>.<span style="color: #202020;">To_Local_Ref</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Resolve_Initial_References</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"RootPOA"</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- We start it up</span>
PortableServer.<span style="color: #202020;">POAManager</span>.<span style="color: #202020;">Activate</span>
<span style="color: #66cc66;">(</span>PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Get_The_POAManager</span> <span style="color: #66cc66;">(</span>Root_POA<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- We create a reference in order to expose it</span>
Ref := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Servant_To_Reference</span>
<span style="color: #66cc66;">(</span>Root_POA, PortableServer.<span style="color: #202020;">Servant</span> <span style="color: #66cc66;">(</span>Obj<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- We display the IOR</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Object_To_String</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
New_Line;
<span style="color: #adadad; font-style: italic;">-- and a corbaloc</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span>
<span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Launch the server. CORBA.ORB.Run is supposed to never return,</span>
<span style="color: #adadad; font-style: italic;">-- print a message if it does.</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Run</span>;
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB main loop terminated!"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> E : <span style="color: #46aa03; font-weight:bold;">others</span> =>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"CBSG server raised "</span> & Ada.<span style="color: #202020;">Exceptions</span>.<span style="color: #202020;">Exception_Information</span> <span style="color: #66cc66;">(</span>E<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">raise</span>;
<span style="color: #00007f;">end</span> Server;</pre>
<p>Even if this code seems complex, it's always the same each time we will expose an object in the bus.<br />
We just have to compile :</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ mkdir obj
fred@coruscant :~/cbsg/corba/Ada $ gnatmake server.adb -D obj -aI../.. `polyorb-config`
</pre>
<p>If everything went well, we just have to start the server</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ ./server
'IOR:010000001700000049444c3a436f726261434253472f434253473a312e30000002000000000000005c000000010102000a0000003132372e302e302e3100f1761b0000002f30303030303030313154643637306239663031326565316538300001000000010000001c0000000100000001000100000000000001010002000000010101000201010003004f503c000000010100000c0000003139322e3136382e332e32007a3300001b0000002f30303030303030313154643637306239663031326565316538300000000000'
'corbaloc:iiop:1.2@127.0.0.1:30449//000000011Td670b9f012ee1e80'
</pre>
<p>if you want the server to listen on another address than 127.0.0.1, we just have to put it in <em>polyorb.conf</em> which must be at the place from which you run the server.<br /></p>
<h3>Waiter, please</h3>
<p>Now that our server is waiting for a client, let's code it. First, a small simple <em>Ada</em> client as everything is ready for it. Once again, the <em>echo</em> example will be enough to create our client</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Command_Line</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">Client</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">Client</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Client <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Command_Line</span>;
<span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">use</span> <span style="color: #46aa03; font-weight:bold;">type</span> CORBA.<span style="color: #202020;">String</span>;
Rcvd_Bullshits : CORBA.<span style="color: #202020;">String</span>;
Bullshit_Generator : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #00007f;">begin</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Initialize</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">if</span> Argument_Count <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">2</span> <span style="color: #00007f;">then</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"usage: client <IOR_string_from_server>"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #adadad; font-style: italic;">-- Get a reference on the distributed object through its IOR or corbaloc</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">String_To_Object</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span>Ada.<span style="color: #202020;">Command_Line</span>.<span style="color: #202020;">Argument</span> <span style="color: #66cc66;">(</span><span style="color: #ff0000;">1</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>, Bullshit_Generator<span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- check that the reference is correct</span>
<span style="color: #00007f;">if</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Is_Nil</span><span style="color: #66cc66;">(</span>Bullshit_Generator<span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"main : cannot invoke on a nil reference"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
Rcvd_Bullshits := CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">createSentence</span><span style="color: #66cc66;">(</span>Bullshit_Generator<span style="color: #66cc66;">)</span>;
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"The generator said : "</span> & CORBA.<span style="color: #202020;">To_Standard_String</span> <span style="color: #66cc66;">(</span>Rcvd_Bullshits<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> E : CORBA.<span style="color: #202020;">Transient</span> =>
<span style="color: #00007f;">declare</span>
Memb : CORBA.<span style="color: #202020;">System_Exception_Members</span>;
<span style="color: #00007f;">begin</span>
CORBA.<span style="color: #202020;">Get_Members</span> <span style="color: #66cc66;">(</span>E, Memb<span style="color: #66cc66;">)</span>;
Put <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"received exception transient, minor"</span><span style="color: #66cc66;">)</span>;
Put <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Unsigned_Long</span>'Image <span style="color: #66cc66;">(</span>Memb.<span style="color: #202020;">Minor</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
Put <span style="color: #66cc66;">(</span><span style="color: #7f007f;">", completion status: "</span><span style="color: #66cc66;">)</span>;
Put_Line <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Completion_Status</span>'Image <span style="color: #66cc66;">(</span>Memb.<span style="color: #202020;">Completed</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span> Client;</pre>
<p>As usual, compilation :</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ gnatmake client -D obj -aI../.. `polyorb-config `
fred@coruscant :~/cbsg/corba/Ada $ ./client 'corbaloc:iiop:1.2@127.0.0.1:30449//000000011Td670b9f012ee1e80'
The generator said : The business leaders embrace a growing execution by thinking outside of the box, whereas the steering committee delivers a top-down interoperability.
</pre>
<p>What to say other than <strong>superb</strong> !!<br />
<br />
Ok, I promised a C++ client with <em>OmniORB</em>. As I always deliver the goods, here it is...<br />
In the C++ directory, we begin by generating the needed files with the <em>OmniORB</em> IDL compiler.</p>
<pre>
fred@coruscant :~/cbsg/corba/C++ $ omniidl -bcxx ../idl/cbsg.idl
</pre>
<p><em>cbsg.hh</em> and <em>cbsg.cc</em> get created. They contain at the same time <em>stubs</em> and <em>skeletons</em>. For the client-side, we will only use the <em>stub</em> part.<br />
We create the client by taking ideas from the provided examples with <em>OmniORB</em> :<br /></p>
<pre class="cpp cpp" style="font-family:inherit"><span style="color: #339900;">#include <cbsg.hh></span>
<span style="color: #339900;">#ifdef HAVE_STD </span>
<span style="color: #339900;">#include <iostream> </span>
<span style="color: #339900;">#include <fstream> </span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #339900;">#else </span>
<span style="color: #339900;">#include <iostream.h></span>
<span style="color: #339900;">#endif </span>
<span style="color: #666666;">////////////////////////////////////////////////////////////////////// </span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">(</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span><span style="color: #000040;">**</span> argv<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000ff;">try</span>
<span style="color: #008000;">{</span>
<span style="color: #666666;">//ORB Initialisation</span>
CORBA<span style="color: #008080;">::</span><span style="color: #007788;">ORB_var</span> orb <span style="color: #000080;">=</span> CORBA<span style="color: #008080;">::</span><span style="color: #007788;">ORB_init</span><span style="color: #008000;">(</span>argc, argv<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">(</span> argc <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"usage: client <object reference>"</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #666666;">//We create the CORBA object from the provided string</span>
CORBA<span style="color: #008080;">::</span><span style="color: #007788;">Object_var</span> obj <span style="color: #000080;">=</span> orb<span style="color: #000040;">-</span><span style="color: #000080;">></span>string_to_object<span style="color: #008000;">(</span>argv<span style="color: #008000;">[</span><span style="color: #0000dd;">1</span><span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//We cast it to CBSG</span>
CorbaCBSG<span style="color: #008080;">::</span><span style="color: #007788;">CBSG_var</span> cbsgRef <span style="color: #000080;">=</span> CorbaCBSG<span style="color: #008080;">::</span><span style="color: #007788;">CBSG</span><span style="color: #008080;">::</span>_narrow<span style="color: #008000;">(</span>obj<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//We check that the object exists</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">(</span> CORBA<span style="color: #008080;">::</span><span style="color: #007788;">is_nil</span><span style="color: #008000;">(</span>cbsgRef<span style="color: #008000;">)</span> <span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Can't narrow reference to type CBSG (or it was nil)."</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #666666;">//And go, we call it</span>
CORBA<span style="color: #008080;">::</span><span style="color: #007788;">String_var</span> bullshit <span style="color: #000080;">=</span> cbsgRef<span style="color: #000040;">-</span><span style="color: #000080;">></span>createSentence<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"The generator said : "</span> <span style="color: #000080;"><<</span> bullshit <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #666666;">//We stop the ORB</span>
orb<span style="color: #000040;">-</span><span style="color: #000080;">></span>destroy<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>CORBA<span style="color: #008080;">::</span><span style="color: #007788;">TRANSIENT</span><span style="color: #000040;">&</span><span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught system exception TRANSIENT -- unable to contact the "</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"server."</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>CORBA<span style="color: #008080;">::</span><span style="color: #007788;">SystemException</span><span style="color: #000040;">&</span> ex<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught a CORBA::"</span> <span style="color: #000080;"><<</span> ex._name<span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>CORBA<span style="color: #008080;">::</span><span style="color: #007788;">Exception</span><span style="color: #000040;">&</span> ex<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught CORBA::Exception: "</span> <span style="color: #000080;"><<</span> ex._name<span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>omniORB<span style="color: #008080;">::</span><span style="color: #007788;">fatalException</span><span style="color: #000040;">&</span> fe<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught omniORB::fatalException:"</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">" file: "</span> <span style="color: #000080;"><<</span> fe.<span style="color: #007788;">file</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">" line: "</span> <span style="color: #000080;"><<</span> fe.<span style="color: #007788;">line</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">" mesg: "</span> <span style="color: #000080;"><<</span> fe.<span style="color: #007788;">errmsg</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span></pre>
<p>We compile and test :</p>
<pre>
fred@coruscant :~/cbsg/corba/C++ $ g++ -o client client.cpp cbsgSK.cc -I. -lomniORB4
fred@coruscant :~/cbsg/corba/C++ $ ./client 'corbaloc:iiop:1.2@127.0.0.1:30449//000000011Td670b9f012ee1e80'
The generator said : The granular low hanging fruit incentivises the steering committee.
</pre>
<p>Depending on the version of <em>OmniORB</em>, it could be necessary to include <q>-lomnithread</q> on the compilation command line.<br />
And that's it !<br />
Well, I promised high availability and <em>tutti quanti</em> but finally, I will keep it for the next time <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
Hope it pleased you.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/24/Spreading-bullshits#rev-pnote-633-1" id="pnote-633-1">1</a>] But just read interfaces, you would get a <q>bullshit</q> overdose</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/24/Spreading-bullshits#rev-pnote-633-2" id="pnote-633-2">2</a>] This second parameter quite obscur is not used by Gautier, so caution :D</p></div>
http://frederic.praca.free.fr/index.php?post/2013/03/24/Spreading-bullshits#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/633Distribution de conneriesurn:md5:7fca88b3bb2430353a9bc718b17f0a132013-03-22T16:31:00+01:002013-03-26T17:54:59+01:00FredDéveloppementAdaCCORBA<p>J'ai décidé aujourd'hui de faire un petit tuto sympa pour réaliser le top du top en matière de <q>scalabilité</q><sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#pnote-632-1" id="rev-pnote-632-1">1</a>]</sup>, de haute distribution ainsi que haute <q>reliabilité</q><sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#pnote-632-2" id="rev-pnote-632-2">2</a>]</sup> tout en restant multi-plateforme, multi-langage et potentiellement multi-paradigme... Enfin, les deux premiers, c'est sûr, le troisième, j'en sais rien et je m'en tape :D<br />
Normalement, là, avec le nombre de <em>buzzwords</em> utilisés, vous devriez déjà avoir le trollomètre au taquet !! :D<br />
Mais je ne vous en dirai pas plus, il faut aller voir, LA SUITE !!!</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#rev-pnote-632-1" id="pnote-632-1">1</a>] J'adore cet anglicisme tellement il est foireux</p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#rev-pnote-632-2" id="pnote-632-2">2</a>] Bien aussi, celui-là</p></div>
<p>Quoi de mieux pour réaliser tout ça que les <em>web services</em> ?<br />
Et bien, c'est simple, autre chose que des <em>web services</em> !! <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
Cette autre chose est un vieux truc que plus personne ne veut utiliser car trop compliqué, trop lourd à mettre en place et à coder, j'ai nommé <em><a href="http://en.wikipedia.org/wiki/Common_Object_Request_Broker_Architecture" hreflang="en" title="CORBA">CORBA</a></em><sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#pnote-632-1" id="rev-pnote-632-1">1</a>]</sup> !!<br />
<br />
Bon, après réflexion, ce ne sera pas un vrai tutoriel <em>CORBA</em>, car il y en a déjà sur Internet, mais plutôt un exemple documenté d'une petite application faite avec <em><a href="http://libre.adacore.com/tools/polyorb" hreflang="en" title="PolyORB">PolyORB</a></em> pour ce qui est du serveur et <em> <a href="http://omniorb.sourceforge.net/" hreflang="en" title="OmniORB">OmniORB</a></em> pour la partie C++ cliente.<br />
<br /></p>
<h4>Le distributeur</h4>
<p>C'est beau comme un titre de films mais que distribuons-nous ?<br />
N'ayant pas envie de recoder toute une application pour la distribuer, j'ai décidé de repartir d'une application existante et rendant régulièrement service. J'ai nommé le <em><a href="http://cbsg.sourceforge.net/cgi-bin/live" hreflang="en" title="CBSG">Corporate Bullshit Generator</a></em> de mon ami adaïste Gautier.<br />
Pour ceux qui ne connaîtraient pas encore, cette application fournit d'excellentes phrases à placer dans toute bonne réunion se déroulant en présence de commerciaux, grands statéguères etc.<br />
Rendez-vous donc sur <a href="http://sourceforge.net/projects/cbsg/" hreflang="en" title="CBSG">la page du projet</a> afin de télécharger le code source<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#pnote-632-2" id="rev-pnote-632-2">2</a>]</sup>.<br />
<br /></p>
<h3>Petite analyse des <q>bullshits</q></h3>
<p>Pour faire du <em>CORBA</em>, il faut d'abord savoir ce que l'on va distribuer. Le paquetage central du <em>CSBG</em> est le <em>Corporate_Bullshit</em>. Il s'agit d'un paquetage générique dont le but est de définir les caractères de saut de lignes ainsi que la phrase à utiliser pour simuler un dialogue<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#pnote-632-3" id="rev-pnote-632-3">3</a>]</sup>.<br />
Quoi qu'on voit ?<br /></p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">function</span> Sentence <span style="color: #00007f;">return</span> String;
<span style="color: #46aa03; font-weight:bold;">function</span> Workshop <span style="color: #00007f;">return</span> String;
<span style="color: #46aa03; font-weight:bold;">function</span> Short_Workshop <span style="color: #00007f;">return</span> String;
<span style="color: #46aa03; font-weight:bold;">function</span> Financial_Report <span style="color: #00007f;">return</span> String;</pre>
<p>Quatre fonctions permettant de créer une chaîne de caractères contenant l'ensemble des <q>bullshits</q>. Soyons fous, nous fournirons donc une interface vers les quatre.<br />
En <em>CORBA</em>, c'est assez simple, cela donnera un fichier <em><a href="http://www.eecg.toronto.edu/~jacobsen/courses/mw/IDL.htm" hreflang="fr" title="IDL">IDL</a></em> comme montrer ci-dessous :</p>
<pre class="cpp cpp" style="font-family:inherit">module CorbaCBSG <span style="color: #008000;">{</span>
interface CBSG<span style="color: #008000;">{</span>
string createSentence<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
string createWorkshop<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
string createShortWorkshop<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
string createFinancialReport<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span><span style="color: #008080;">;</span></pre>
<p>Ici, j'ai préféré respecter les conventions d'écriture en vigueur en C++, Java et consorts en lieu et place de celles d'Ada pour ne pas effrayer le programmeur qui voudrait écrire un client dans ces langages <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /><br />
Au final, c'est bête comme chou ! :D<br />
<br />
Mais ce n'est qu'un premier exemple...<br />
<br /></p>
<h3>Génération</h3>
<p>Passons maintenant à la génération et à l'implémentation de la partie serveur.<br />
Pour cela, je conseille la création d'un répertoire <em>corba</em> contenant un répertoire <em>idl</em> ainsi que des répertoires <em>Ada</em> et <em>C++</em>, le tout dans le répertoire du <em>cbsg</em>. Le fichier <em>cbsg.idl</em> définit au-dessus trouvera aisément sa place dans le répertoire <em>idl</em>.<br />
Passons aux choses sérieuses :</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ iac -i ../idl/cbsg.idl
</pre>
<p>Onze fichiers sont normalement créés. Seul les fichiers <em>corbacbsg-cbsg-impl.ads</em> et <em>corbacbsg-cbsg-impl.adb</em> vont nous intéresser, le reste étant de la tuyauterie <em>CORBA</em>. Un point toutefois important, l'option <em>i</em> écrasera votre implémentation si celle-ci existe déjà ainsi que sa spécification si elle contient des champs spécifiques.<br />
Dans la spécification (fichier <em>ads</em>), il n'y a rien à changer. En effet, notre objet <em>CORBA</em> n'a pas d'état en soi tout comme le <em>CBSG</em>.<br />
Par contre, il est intéressant de lire ce fichier car le lecteur attentif aura remarqué que les méthodes générées n'utilisent pas le type <em>String</em> standard d<em>'Ada</em> mais un type propre à <em>CORBA</em>. Notre objet <em>CORBA</em> fera donc la translation.<br />
Comme vous êtes très forts, je ne donnerai que l'implémentation de la fonction <em>createSentence</em> ainsi que la déclaration du paquetage générique <em>Corporate_Bullshit</em> , vous généraliserez par vous-mêmes :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">package</span> Simple_Generator <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Corporate_Bullshit<span style="color: #66cc66;">(</span>Paragraph => <span style="color: #7f007f;">""</span>,
Dialog_Mark => <span style="color: #7f007f;">""</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">--------------------</span>
<span style="color: #adadad; font-style: italic;">-- createSentence --</span>
<span style="color: #adadad; font-style: italic;">--------------------</span>
<span style="color: #46aa03; font-weight:bold;">function</span> createSentence
<span style="color: #66cc66;">(</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Object<span style="color: #66cc66;">)</span>
<span style="color: #00007f;">return</span> CORBA.<span style="color: #202020;">String</span>
<span style="color: #00007f;">is</span>
Generated_Sentence : String := Simple_Generator.<span style="color: #202020;">Sentence</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">return</span> CORBA.<span style="color: #202020;">To_CORBA_String</span><span style="color: #66cc66;">(</span>Generated_Sentence<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span> createSentence;</pre>
<p>Maintenant que nous avons défini le comportement de notre objet, il nous faut démarrer le bus <em>CORBA</em> et exposer une instance de notre toute nouvelle classe.<br />
Pour le moment, nous n'utiliserons pas l'un des services primordiaux de <em>CORBA</em>, à savoir le <em>Name Service</em>. Notre serveur exposera donc seulement une <em><a href="http://en.wikipedia.org/wiki/Interoperable_Object_Reference" hreflang="en" title="IOR">IOR</a></em>, référence vers notre objet.<br />
Pour ce serveur, l'exemple <em>echo</em> fournit avec <em>PolyORB</em> suffit amplement :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Exceptions</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">Object</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PortableServer.<span style="color: #202020;">POAManager</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Impl</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>;
<span style="color: #adadad; font-style: italic;">-- Permet de spécifier à PolyORB son type de fonctionnement</span>
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">No_Tasking_Server</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Server <span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- Permet de récupérer les paramètres tels que définis dans le norme CORBA comme InitialRef</span>
Argv : CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Arg_List</span> := CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Command_Line_Arguments</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Initialisation de notre bus sous le nom ORB</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Init</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>, Argv<span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">declare</span>
<span style="color: #adadad; font-style: italic;">-- Le PortableObjectAdapter est l'endroit où sont stockés nons objets</span>
Root_POA : PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Local_Ref</span>;
<span style="color: #adadad; font-style: italic;">-- On déclare une référence pour notre objet</span>
Ref : CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #adadad; font-style: italic;">-- Et son implémentation</span>
Obj : <span style="color: #46aa03; font-weight:bold;">constant</span> CORBA.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object_Ptr</span> := <span style="color: #46aa03; font-weight:bold;">new</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Impl</span>.<span style="color: #202020;">Object</span>;
<span style="color: #00007f;">begin</span>
<span style="color: #adadad; font-style: italic;">-- Récupération du POA racine du bus</span>
<span style="color: #adadad; font-style: italic;">-- Il s'agit d'une interface CORBA et utilise donc des chaines de caractères CORBA</span>
<span style="color: #adadad; font-style: italic;">-- que l'on traduit en référence d'objet</span>
Root_POA := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Helper</span>.<span style="color: #202020;">To_Local_Ref</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Resolve_Initial_References</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"RootPOA"</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- On démarre notre POA</span>
PortableServer.<span style="color: #202020;">POAManager</span>.<span style="color: #202020;">Activate</span>
<span style="color: #66cc66;">(</span>PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Get_The_POAManager</span> <span style="color: #66cc66;">(</span>Root_POA<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- On crée une référence sur notre objet pour l'exposer</span>
Ref := PortableServer.<span style="color: #202020;">POA</span>.<span style="color: #202020;">Servant_To_Reference</span>
<span style="color: #66cc66;">(</span>Root_POA, PortableServer.<span style="color: #202020;">Servant</span> <span style="color: #66cc66;">(</span>Obj<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Et on affiche un IOR</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span> <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Object</span>.<span style="color: #202020;">Object_To_String</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
New_Line;
<span style="color: #adadad; font-style: italic;">-- et une corbaloc</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"'"</span>
& CORBA.<span style="color: #202020;">To_Standard_String</span>
<span style="color: #66cc66;">(</span>PolyORB.<span style="color: #202020;">CORBA_P</span>.<span style="color: #202020;">CORBALOC</span>.<span style="color: #202020;">Object_To_Corbaloc</span> <span style="color: #66cc66;">(</span>Ref<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
& <span style="color: #7f007f;">"'"</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Launch the server. CORBA.ORB.Run is supposed to never return,</span>
<span style="color: #adadad; font-style: italic;">-- print a message if it does.</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Run</span>;
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB main loop terminated!"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> E : <span style="color: #46aa03; font-weight:bold;">others</span> =>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"CBSG server raised "</span> & Ada.<span style="color: #202020;">Exceptions</span>.<span style="color: #202020;">Exception_Information</span> <span style="color: #66cc66;">(</span>E<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">raise</span>;
<span style="color: #00007f;">end</span> Server;</pre>
<p>Même si ce code a l'air complexe, il est quasi identique pour toutes les fois où l'on doit exposer un objet sur le bus.<br />
Il ne reste plus que la compilation :</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ mkdir obj
fred@coruscant :~/cbsg/corba/Ada $ gnatmake server.adb -D obj -aI../.. `polyorb-config`
</pre>
<p>Si tout c'est bien passé, il ne reste qu'à lancer notre serveur</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ ./server
'IOR:010000001700000049444c3a436f726261434253472f434253473a312e30000002000000000000005c000000010102000a0000003132372e302e302e3100f1761b0000002f30303030303030313154643637306239663031326565316538300001000000010000001c0000000100000001000100000000000001010002000000010101000201010003004f503c000000010100000c0000003139322e3136382e332e32007a3300001b0000002f30303030303030313154643637306239663031326565316538300000000000'
'corbaloc:iiop:1.2@127.0.0.1:30449//000000011Td670b9f012ee1e80'
</pre>
<p>vous voulez que le serveur écoute sur autre chose que 127.0.0.1, il suffit de le préciser dans le fichier <em>polyorb.conf</em> qui devra se trouver à l'endroit d'où vous lancez le serveur.<br /></p>
<h3>Serveur, s'il vous plaît</h3>
<p>Maintenant que notre serveur attend le client, codons-le. D'abord un petit client tout simple en <em>Ada</em> vu que tout est prêt pour cela. Encore une fois, l'exemple <em>echo</em> fourni nous suffira pour créer notre client</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Command_Line</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CORBA.<span style="color: #202020;">ORB</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>;
<span style="color: #46aa03; font-weight:bold;">with</span> PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">Client</span>;
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">(</span>Off, PolyORB.<span style="color: #202020;">Setup</span>.<span style="color: #202020;">Client</span><span style="color: #66cc66;">)</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Client <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Command_Line</span>;
<span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_IO</span>;
<span style="color: #46aa03; font-weight:bold;">use</span> <span style="color: #46aa03; font-weight:bold;">type</span> CORBA.<span style="color: #202020;">String</span>;
Rcvd_Bullshits : CORBA.<span style="color: #202020;">String</span>;
Bullshit_Generator : CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Ref</span>;
<span style="color: #00007f;">begin</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">Initialize</span> <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"ORB"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">if</span> Argument_Count <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #ff0000;">1</span> .. <span style="color: #ff0000;">2</span> <span style="color: #00007f;">then</span>
Put_Line
<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"usage: client <IOR_string_from_server>"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
<span style="color: #adadad; font-style: italic;">-- Récupération d'une référence sur l'objet distribué par son IOR ou corbaloc</span>
CORBA.<span style="color: #202020;">ORB</span>.<span style="color: #202020;">String_To_Object</span>
<span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">To_CORBA_String</span> <span style="color: #66cc66;">(</span>Ada.<span style="color: #202020;">Command_Line</span>.<span style="color: #202020;">Argument</span> <span style="color: #66cc66;">(</span><span style="color: #ff0000;">1</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>, Bullshit_Generator<span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- On vérifie que la référence est correcte</span>
<span style="color: #00007f;">if</span> CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">Is_Nil</span><span style="color: #66cc66;">(</span>Bullshit_Generator<span style="color: #66cc66;">)</span> <span style="color: #00007f;">then</span>
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"main : cannot invoke on a nil reference"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">return</span>;
<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;
Rcvd_Bullshits := CorbaCBSG.<span style="color: #202020;">CBSG</span>.<span style="color: #202020;">createSentence</span><span style="color: #66cc66;">(</span>Bullshit_Generator<span style="color: #66cc66;">)</span>;
Put_Line <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"The generator said : "</span> & CORBA.<span style="color: #202020;">To_Standard_String</span> <span style="color: #66cc66;">(</span>Rcvd_Bullshits<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">exception</span>
<span style="color: #46aa03; font-weight:bold;">when</span> E : CORBA.<span style="color: #202020;">Transient</span> =>
<span style="color: #00007f;">declare</span>
Memb : CORBA.<span style="color: #202020;">System_Exception_Members</span>;
<span style="color: #00007f;">begin</span>
CORBA.<span style="color: #202020;">Get_Members</span> <span style="color: #66cc66;">(</span>E, Memb<span style="color: #66cc66;">)</span>;
Put <span style="color: #66cc66;">(</span><span style="color: #7f007f;">"received exception transient, minor"</span><span style="color: #66cc66;">)</span>;
Put <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Unsigned_Long</span>'Image <span style="color: #66cc66;">(</span>Memb.<span style="color: #202020;">Minor</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
Put <span style="color: #66cc66;">(</span><span style="color: #7f007f;">", completion status: "</span><span style="color: #66cc66;">)</span>;
Put_Line <span style="color: #66cc66;">(</span>CORBA.<span style="color: #202020;">Completion_Status</span>'Image <span style="color: #66cc66;">(</span>Memb.<span style="color: #202020;">Completed</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span>;
<span style="color: #00007f;">end</span> Client;</pre>
<p>Comme d'habitude, compilation :</p>
<pre>
fred@coruscant :~/cbsg/corba/Ada $ gnatmake client -D obj -aI../.. `polyorb-config `
fred@coruscant :~/cbsg/corba/Ada $ ./client 'corbaloc:iiop:1.2@127.0.0.1:30449//000000011Td670b9f012ee1e80'
The generator said : The business leaders embrace a growing execution by thinking outside of the box, whereas the steering committee delivers a top-down interoperability.
</pre>
<p>Que dire de plus que <strong>magnifique</strong> !!<br />
<br />
Ok, j'avais promis un client C++ avec <em>OmniORB</em>. Comme je tiens toujours mes promesses, le voici...<br />
Dans le répertoire C++, on commence donc par générer les fichiers nécessaires avec le compilateur d'IDL d<em>'OmniORB</em>.</p>
<pre>
fred@coruscant :~/cbsg/corba/C++ $ omniidl -bcxx ../idl/cbsg.idl
</pre>
<p>Les fichiers <em>cbsg.hh</em> et <em>cbsg.cc</em> sont créés. Ils contiennent à la fois les <em>stubs</em> et les <em>skeletons</em>. Dans le cadre du client, on n'utilisera que la partie <em>stub</em>.<br />
on crée donc le client en s'inspirant des exemples fournis avec <em>OmniORB</em> :<br /></p>
<pre class="cpp cpp" style="font-family:inherit"><span style="color: #339900;">#include <cbsg.hh></span>
<span style="color: #339900;">#ifdef HAVE_STD </span>
<span style="color: #339900;">#include <iostream> </span>
<span style="color: #339900;">#include <fstream> </span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #339900;">#else </span>
<span style="color: #339900;">#include <iostream.h></span>
<span style="color: #339900;">#endif </span>
<span style="color: #666666;">////////////////////////////////////////////////////////////////////// </span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">(</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span><span style="color: #000040;">**</span> argv<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000ff;">try</span>
<span style="color: #008000;">{</span>
<span style="color: #666666;">//Initialisation de l'ORB</span>
CORBA<span style="color: #008080;">::</span><span style="color: #007788;">ORB_var</span> orb <span style="color: #000080;">=</span> CORBA<span style="color: #008080;">::</span><span style="color: #007788;">ORB_init</span><span style="color: #008000;">(</span>argc, argv<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">(</span> argc <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"usage: client <object reference>"</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #666666;">//On crée un objet CORBA à partir de la chaine fournie</span>
CORBA<span style="color: #008080;">::</span><span style="color: #007788;">Object_var</span> obj <span style="color: #000080;">=</span> orb<span style="color: #000040;">-</span><span style="color: #000080;">></span>string_to_object<span style="color: #008000;">(</span>argv<span style="color: #008000;">[</span><span style="color: #0000dd;">1</span><span style="color: #008000;">]</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//Et le castons en CBSG</span>
CorbaCBSG<span style="color: #008080;">::</span><span style="color: #007788;">CBSG_var</span> cbsgRef <span style="color: #000080;">=</span> CorbaCBSG<span style="color: #008080;">::</span><span style="color: #007788;">CBSG</span><span style="color: #008080;">::</span>_narrow<span style="color: #008000;">(</span>obj<span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//On vérifie que l'objet existe</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">(</span> CORBA<span style="color: #008080;">::</span><span style="color: #007788;">is_nil</span><span style="color: #008000;">(</span>cbsgRef<span style="color: #008000;">)</span> <span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Can't narrow reference to type CBSG (or it was nil)."</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #666666;">//Et hop, on appelle</span>
CORBA<span style="color: #008080;">::</span><span style="color: #007788;">String_var</span> bullshit <span style="color: #000080;">=</span> cbsgRef<span style="color: #000040;">-</span><span style="color: #000080;">></span>createSentence<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"The generator said : "</span> <span style="color: #000080;"><<</span> bullshit <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #666666;">//On arrête l'ORB</span>
orb<span style="color: #000040;">-</span><span style="color: #000080;">></span>destroy<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>CORBA<span style="color: #008080;">::</span><span style="color: #007788;">TRANSIENT</span><span style="color: #000040;">&</span><span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught system exception TRANSIENT -- unable to contact the "</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"server."</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>CORBA<span style="color: #008080;">::</span><span style="color: #007788;">SystemException</span><span style="color: #000040;">&</span> ex<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught a CORBA::"</span> <span style="color: #000080;"><<</span> ex._name<span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>CORBA<span style="color: #008080;">::</span><span style="color: #007788;">Exception</span><span style="color: #000040;">&</span> ex<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught CORBA::Exception: "</span> <span style="color: #000080;"><<</span> ex._name<span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">catch</span><span style="color: #008000;">(</span>omniORB<span style="color: #008080;">::</span><span style="color: #007788;">fatalException</span><span style="color: #000040;">&</span> fe<span style="color: #008000;">)</span>
<span style="color: #008000;">{</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">"Caught omniORB::fatalException:"</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">" file: "</span> <span style="color: #000080;"><<</span> fe.<span style="color: #007788;">file</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">" line: "</span> <span style="color: #000080;"><<</span> fe.<span style="color: #007788;">line</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #0000dd;">cerr</span> <span style="color: #000080;"><<</span> <span style="color: #FF0000;">" mesg: "</span> <span style="color: #000080;"><<</span> fe.<span style="color: #007788;">errmsg</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span> <span style="color: #000080;"><<</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">}</span>
<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">}</span></pre>
<p>On compile et on teste</p>
<pre>
fred@coruscant :~/cbsg/corba/C++ $ g++ -o client client.cpp cbsgSK.cc -I. -lomniORB4
fred@coruscant :~/cbsg/corba/C++ $ ./client 'corbaloc:iiop:1.2@127.0.0.1:30449//000000011Td670b9f012ee1e80'
The generator said : The granular low hanging fruit incentivises the steering committee.
</pre>
<p>Suivant la version d<em>'OmniORB</em>, il peut être nécessaire de compléter la ligne de compilation avec <q>-lomnithread</q>.<br />
Et voilà !<br />
Bon, j'avais promis de la haute disponibilité et <em>tutti quanti</em> mais finalement, on va garder ça pour la prochaine fois <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
En espérant que cela vous a plu.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#rev-pnote-632-1" id="pnote-632-1">1</a>] Désolé mais la page en français est beaucoup trop incomplête <img src="/themes/default/smilies/sad.png" alt=":(" class="smiley" /></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#rev-pnote-632-2" id="pnote-632-2">2</a>] Mais ne lisez que les interfaces, vous risqueriez de choper une overdose de <q>bullshits</q></p>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#rev-pnote-632-3" id="pnote-632-3">3</a>] Ce second paramètre assez obscure n'est pas utilisé par Gautier donc prudence :D</p></div>
http://frederic.praca.free.fr/index.php?post/2013/03/22/Distribution-de-conneries#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/632Merci de fermer les portes !urn:md5:c1526624f970a0acb8da85edb28c66ae2013-02-13T14:17:00+01:002013-02-13T15:27:53+01:00FredSystème et réseauSubversion <p>J'aurais pu sous-titrer ce billet <em>Quand la confiance ne règne plus</em> <img src="/themes/default/smilies/confused.png" alt=":-/" class="smiley" /><br />
<br />
Il m 'avait déjà été demandé par le passé de sécuriser l'accès à un serveur <em>Subversion</em> mais vu les effets de bord, j'étais revenu en arrière, histoire de pas embêter mes petits camarades développeurs.<br />
Comme toutes les choses ont une fin, c'est reparti de plus belle.<br />
Heureusement, cette fois-ci, j'ai réussi à m'y coller, non sans avoir foutu un beau bordel pendant quelques heures.<br />
Je vais quand même tenter de vous expliquer ce qu'il y avait à faire et comment je suis arrivé à mes fins.<br />
Ça vous semblera peut-être très simple mais il y avait des pièges.
<br />
Imaginons un référentiel <em>Subversion</em> ayant la structure suivante :</p>
<pre>
/
├── Projet1
│ ├── branches
│ ├── tags
│ └── trunk
└── Projet2
├── branches
├── tags
└── trunk
</pre>
<p>Un exemple simple de fichier d'accès est le suivant :</p>
<pre>
[groups]
projet1_devs=john, joe
projet1_admins=john
projet2_devs=jane, joe
projet2_admins=jane
[/]
* = r
[Projet1]
@projet1_devs = r
[Projet1/tags]
@projet1_admins = rw
@projet1_devs = r
[Projet1/branches]
@projet1_devs = rw
#Et ainsi de suite pour chaque projet
</pre>
<p>Jusque là, c'est pas trop grave mais tous les développeurs peuvent voir le code de chaque projet mais ne peuvent pas y écrire, on est typiquement dans le cas classique tel que décrit <a href="http://svnbook.red-bean.com/en/1.7/svn.serverconfig.pathbasedauthz.html" hreflang="en" title="Subversion Auth">dans la doc</a>.<br />
Tant que l'on a confiance, pas de problème mais quand le doute vous habite, ça va plus.<br />
Allons-y, fermons les portes !<br />
<br />
Le premier réflexe est de retirer la partie liée au <em><a href="http://frederic.praca.free.fr/" title="/">/</a></em>... C'est une bonne idée mais dont le principal effet de bord est de gêner les outils de navigation dans le référentiel et qui oblige le développeur à connaître l'URL complète vers son projet.<br />
Alors comment faire pour continuer à pouvoir <em>browser</em> tranquillement mais que dans les projets où on a les droits ?<br />
Et bien, au lieu de mettre des droits, on en retire explicitement :<br /></p>
<pre>
[groups]
projet1_devs=john, joe
projet1_admins=john
projet2_devs=jane, joe
projet2_admins=jane
[/]
* = r
[Projet1]
* =
@projet1_devs = r
[Projet1/tags]
* =
@projet1_admins = rw
@projet1_devs = r
[Projet1/branches]
* =
@projet1_devs = rw
#Et ainsi de suite pour chaque projet
</pre>
<p>Vous avez remarqué la subtilité ?<br />
Pour chaque section de projet, il suffit de retirer les droits mis à tous.<br />
Bon, c'est simple mais fallait y penser.</p>http://frederic.praca.free.fr/index.php?post/2013/02/13/Merci-de-fermer-les-portes-%21#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/631Bissection !urn:md5:5161717ddc8d27ac4e7ee225266fe0122012-12-20T22:14:00+01:002012-12-20T22:49:18+01:00FredDéveloppementMonotone<p>non, je n'ai pas décidé de faire des expériences sur des animaux !<br />
Non, je n'ai pas décidé de me faire greffer un deuxième organe sexuel, le mien me suffit<sup>[<a href="http://frederic.praca.free.fr/index.php?post/2012/12/20/Bissection-%21#pnote-630-1" id="rev-pnote-630-1">1</a>]</sup>.<br />
J'ai décidé de faire un petit billet sur cette fonctionnalité que l'on trouve dans certains logiciels de gestion de versions qui n'est pas mal car elle aide à faire la recherche de la version qui a introduit une régression dans un logiciel.<br />
D'ailleurs, il est normal de la trouver dans <em>Monotone</em>, <em>Git</em> et <em>Mercurial</em> vu que les historiques ne sont pas forcément linéaires.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://frederic.praca.free.fr/index.php?post/2012/12/20/Bissection-%21#rev-pnote-630-1" id="pnote-630-1">1</a>] Plus, ce serait inconvenant :D</p></div>
<p>Pour ceux qui ne le sauraient pas, je suis fan de <a href="http://monotone.ca" hreflang="en" title="Monotone">''Monotone''</a>, un beau logiciel de gestion des versions qui fut, d'après la légende, une source d'inspiration pour un certain Linus T. au moment de créer un autre logiciel dont j'ai parlé <a href="http://frederic.praca.free.fr/index.php?post/2012/11/26/A-l-abri-dans-ma-Git-oune" hreflang="en" title="Monotone">ici</a>.<br />
<br />
Mais là, ce n'est pas pour casser du sucre sur le dos des autres VCS que j'écris mais pour présenter une fonctionnalité intéressante de <em>Monotone</em>, j'ai nommé le <a href="http://www.monotone.ca/docs/Bisecting.html#Bisecting" hreflang="en" title="Bisecting">''bisecting''</a>.<br />
But de l'opération ? Retrouver LA version qui a introduit une ou plusieurs régressions dans un logiciel.<br />
Allons-y gaiement pour la démo !<br />
Toutes les étapes seront détaillées mais il est possible d'utiliser la base de données attachée à ce billet.<br />
<br />
Tout d'abord, on initialise une base de données <em>Monotone</em>.<br /></p>
<pre>
fred@dagobah:~/Dev$ mtn --db=bisect_test.mtn db init
</pre>
<p>Rien de monstrueux alors on continue en créant notre projet</p>
<pre>
fred@dagobah:~/Dev$ mtn --db=bisect_test.mtn --branch=bisect_test setup bisect_test
</pre>
<p>Là encore, si vous suivez le <a href="http://www.monotone.ca/docs/Tutorial.html#Tutorial" hreflang="en" title="Tuto">tutorial</a> de <em>Monotone</em>, toujours rien d'extraordinaire. Ajoutons un peu de code pour notre première version dans le répertoire <em>bisect_test</em> :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_Io</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_Io</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Bisect <span style="color: #00007f;">is</span>
<span style="color: #00007f;">begin</span>
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"Hello world"</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span> Bisect;</pre>
<p>Ok, c'est nul <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
On ajoute et on <em>committe</em></p>
<pre>
fred@dagobah:~/Dev$ mtn add bisect.adb
fred@dagobah:~/Dev$ mtn ci
</pre>
<p>Après avoir saisi notre message et notre mot de passe, on a notre version. On continue :</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_Io</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_Io</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Bisect <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">type</span> My_Type <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #ff0000;">12</span>..<span style="color: #ff0000;">21</span>;
My_Var : My_Type := <span style="color: #ff0000;">12</span>;
<span style="color: #00007f;">begin</span>
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"Hello world"</span><span style="color: #66cc66;">)</span>;
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"My_Var="</span> & My_Type'Image<span style="color: #66cc66;">(</span>My_Var<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
<span style="color: #00007f;">end</span> Bisect;</pre>
<p>Rebelote, on <em>committe</em> et on refait une modif... Bon, je vais pas tout mettre là mais ce qui est intéressant, c'est d'introduire une erreur et de refaire une version après. Voilà la version finale qui finalement compile mais comme le dit le compilateur, ça va foirer <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
Merci Ada !</p>
<pre class="ada ada" style="font-family:inherit"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Text_Io</span>; <span style="color: #46aa03; font-weight:bold;">use</span> Ada.<span style="color: #202020;">Text_Io</span>;
<span style="color: #46aa03; font-weight:bold;">procedure</span> Bisect <span style="color: #00007f;">is</span>
<span style="color: #46aa03; font-weight:bold;">type</span> My_Type <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">range</span> <span style="color: #ff0000;">12</span>..<span style="color: #ff0000;">21</span>;
My_Var : My_Type := <span style="color: #ff0000;">11</span>;
<span style="color: #00007f;">begin</span>
Put_Line<span style="color: #66cc66;">(</span><span style="color: #7f007f;">"Hello world"</span><span style="color: #66cc66;">)</span>;
<span style="color: #adadad; font-style: italic;">-- Put_Line("My_Var=" & My_Type'Image(My_Var));</span>
<span style="color: #00007f;">end</span> Bisect;</pre>
<p>Le problème, c'est que cela n'a pas été fait dans cette révision mais une ou plusieurs révisions avant.<br />
Vite, retrouvons le coupable sans faire de recherche par lecture du code mais par le test.<br />
On commence par marquer la révision courante comme foireuse :</p>
<pre>
fred@dagobah:~/Dev$ mtn bisect bad
mtn: bissection débutée à la révision « 99c46344761c157cabd4e8e41e9fb6d3a0442a92 frederic.praca@free.fr 20/12/2012 21:51:39 »
mtn: révisions en cours de bissection ; 0 bonnes, 1 mauvaises, 0 sautées. Veuillez spécifier les bonnes révisions pour débuter la recherche.
</pre>
<p>Bien sûr, vos révisions n'auront pas forcément les mêmes identifiants.<br />
Maintenant, on retourne à la version que l'on sait fonctionner pour la marquer comme correcte :</p>
<pre>
fred@dagobah:~/Dev/bisect_test$ mtn update -r 5e78416bc66278692a30f1a807aa00b25f31ca56
mtn: sélection de la cible 5e78416bc66278692a30f1a807aa00b25f31ca56 pour la mise à jour
mtn: [gauche] 75b7d43d6a0d02baa366d48984c259a8f6df755e
mtn: [droite] 5e78416bc66278692a30f1a807aa00b25f31ca56
mtn: mise à jour de « bisect.adb »
mtn: mise à jour vers la révision de base 5e78416bc66278692a30f1a807aa00b25f31ca56
fred@dagobah:~/Dev/bisect_test$ mtn bisect good
mtn: 4 révisions en cours de bissection ; 1 bonnes, 1 mauvaises, 0 sautées, 2 restantes
mtn: mise à jour vers 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 frederic.praca@free.fr 20/12/2012 21:51:19
mtn: mise à jour de « bisect.adb »
</pre>
<p>Et voilà, on vient de préparer la dichotomie. Une petite vérification</p>
<pre>
fred@dagobah:~/Dev/bisect_test$ mtn bisect status
mtn: 4 révisions en cours de bissection ; 1 bonnes, 1 mauvaises, 0 sautées, 2 restantes
mtn: avertissement : prochaine révision pour le test de bissection est e941bd9f9386dd74860eba21a43b35c064c41425
mtn: avertissement : toutefois, cet espace de travail est actuellement à 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4
mtn: avertissement : exécutez « bisect update » pour mettre à jour vers cette révision avant de tester
</pre>
<p>L'outil nous dit même comment faire, si c'est pas du luxe !! <img src="/themes/default/smilies/smile.png" alt=":)" class="smiley" /><br />
Alors, on y va</p>
<pre>
fred@dagobah:~/Dev/bisect_test$ mtn bisect update
mtn: 4 révisions en cours de bissection ; 1 bonnes, 1 mauvaises, 0 sautées, 2 restantes
mtn: mise à jour vers e941bd9f9386dd74860eba21a43b35c064c41425 frederic.praca@free.fr 20/12/2012 21:50:33
mtn: mise à jour de « bisect.adb »
</pre>
<p>Si vous avez bien regardé la base de données fournie ou votre propre base, vous vous rendrez compte que la version vers laquelle on a mis à jour n'est pas juste la suivante mais celle qui se trouve au milieu des révisions, de la dichotomie quoi !<br />
On teste et comme ça marche, on le dit à l'outil.</p>
<pre>
fred@dagobah:~/Dev/bisect_test$ mtn bisect good
mtn: 4 révisions en cours de bissection ; 2 bonnes, 1 mauvaises, 0 sautées, 1 restantes
mtn: mise à jour vers 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 frederic.praca@free.fr 20/12/2012 21:51:19
mtn: mise à jour de « bisect.adb »
</pre>
<p>Et là encore, on se retrouve à mi-chemin entre la dernière bonne et la mauvaise.<br />
Cette fois-ci, on la teste et... Bang !!! Ça part au tapis !!<br />
Encore une fois, on le dit à l'outil</p>
<pre>
fred@dagobah:~/Dev/bisect_test$ mtn bisect bad
mtn: 4 révisions en cours de bissection ; 2 bonnes, 2 mauvaises, 0 sautées, 0 restantes
mtn: bissection terminée à la révision « 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 frederic.praca@free.fr 20/12/2012 21:51:19 »
</pre>
<p>Et là... Youpi !!! La bissection est terminée, la première version qui a introduit l'erreur est trouvée quand la dernière révision restante est marquée comme mauvaise.<br />
Maintenant, il y a plusieurs options :</p>
<ul>
<li>Corriger et <em>committer</em> en créant une divergence</li>
<li>Désapprouver avec <em>disapprove</em> la version foireuse</li>
</ul>
<p>Enfin, il ne faut pas oublier de faire un <em>mtn bisect reset</em> pour retirer les informations de bissection.<br />
Voili, voilou, une bonne façon de retrouver des régressions :D<br />
Amusez-vous bien !</p>http://frederic.praca.free.fr/index.php?post/2012/12/20/Bissection-%21#comment-formhttp://frederic.praca.free.fr/index.php?feed/atom/comments/630