Information ou critique irraisonnée ?

D’habitude, j’aime bien les articles de L’Informaticien, parce qu’ils sont assez équilibrés et neutres. Je ne sais pas trop quel type de moutarde est monté au nez de Stéphane Larcher pour écrire cet article, mais je l’ai trouvé inutilement méprisant, et même injurieux par moment. On n’est pas habitués à voir dans un article sur l’informatique des commentaires comme “Ils doivent impérativement arrêter (ou commencer) la drogue”, ou bien “taré congénital” ou encore “Dans quelles écoles de commerce et de marketing ces « analystes » ont-ils fait leurs études ? Qu’ils nous le disent afin que nous n’y envoyions pas nos enfants”. Et la conclusion est encore pire : je préfère ne pas la recopier…

Perso, je ne suis pas fan d’Apple, mais ils font des produits de bonne qualité, et peuvent se permettre d’être plus chers. Par contre, pour le Mini, ils sont trop hauts, et c’est l’avis d’une énorme majorité de commentateurs. C’est difficile à nier… Maintenant, citer – comme l’auteur le fait – cette majorité pour lui expliquer qu’elle n’a rien compris, le moins qu’on puisse dire est que c’est assez arrogant. Et là où ça sent bon le populisme, c’est que tous les gens qui sont de cet avis sont catalogués sous le nom générique des “analystes”, ou encore “ces doctes personnages”. C’est un peu la même chose que, au choix, “experts” ou “technocrates” : des gens qui se croient très fort mais n’ont pas compris, tous autant bardés de certitudes qu’ils sont, ce que l’auteur de l’article, lui, a compris tout seul. Applaudissements s’il vous plait, car Stéphane Larcher a raison, seul contre tous !

On s’approche de l’escroquerie intellectuelle lorsque, quelques lignes plus bas, l’auteur annonce être prêt à reconnaitre son erreur publiquement si le futur lui donnait tort. Mais pensez-vous qu’il donne une date ou une limite de taille de marché pour l’iPad Mini en dessous de laquelle il le fera ? Que nenni… Sachant que, quelques lignes plus haut à peine, l’auteur prévoyait des résultats trimestriels d’Apple qui “casseraient la baraque”, que ceux-ci ont été en demi-teinte, peut-être faudrait-il commencer par reconnaitre cette erreur-ci ?

Voilà, c’était le billet d’humeur du moment. Rassurez-vous : on repart sur la technique dès le prochain, avec un petit projet de reconnaissance de lettres sur Kinect.

Posted in Uncategorized | Leave a comment

L’informatique et les voitures

Toujours ce vieux lien qu’on cherche à faire entre l’informatique et l’industrie automobile. On aura beau expliquer en long et en large que c’est comme comparer un fil à linge et un topinambour, ça nous collera toujours aux basques comme le sparadrap aux doigts du Capitaine Haddock.

Google et le taxi

En faisant ma petite veille informatique habituelle, je suis tombé sur ce document de Google (dixit L’Informaticien, mais il n’y a pas de signature) qui m’a sidéré… Comment en effet ne pas être ébahi par autant de mauvaise foi ? Pour planter le décor : Google use de son statut de moteur de recherche le plus utilisé pour centraliser l’information collectée par les organes de presse qui paient des journalistes pour cela, et ce bien sûr sans leur reverser quoi que ce soit.

Sur ce, le gouvernement s’en mêle, et propose un “lex Google”. Que ce soit une bonne idée ou pas, comment la faire, etc., tout ça se discute. Mais ce qui me fait tomber à la renverse est l’argumentation développée par Google (le seul fait qu’une entreprise se place au même niveau qu’un Etat souverain en argumentant étant déjà assez irritant) :

Exiger de Google une rémunération au motif que son moteur de recherche dirige des lecteurs vers les sites de presse n’a pas plus de sens que d’exiger d’un taxiste qui conduit un client à un restaurant de rémunérer le restaurateur.

Comparons ce qui est comparable : imaginez vous dans une ville où une compagnie et une seule possède 95% des taxis, et que, forte de ce quasi-monopole, cette société demande aux restaurateurs de leur donner gratuitement des imprimés des menus pour qu’elle puisse les proposer comme un service d’information aux gens qui se font conduire.

En tant que restaurateur, si vous refusez, vous pouvez faire une croix sur toute la clientèle de passage qui prend un taxi pour venir manger en ville. Si vous acceptez, vous supportez seul le coût d’imprimer les menus, sans même avoir une garantie que le taxi les mettra en avant.

Ca ne vous pas fait penser à Naples, ce genre d’histoire ?

Good car, bad computer

Dans la même veine de comparaison avec l’industrie automobile (et le lien est plus direct), un autre article qui fait bondir : The failed record of the software industry–why software people don’t get it, de Jeffrey Palermo, où l’auteur nous explique que les “gens de l’informatique” (c’est bien vague) ne captent tout simplement pas…

Et c’est reparti sur la comparaison moisie entre les deux industries, et l’auteur citant le nombre effarant de projets informatiques en état d’échec, pour les comparer aux projets automobiles qui, comme tout le monde le sait, aboutissent toujours en temps et en heure, dans le budget choisi et avec une qualité parfaite. Et comment pourrait-il en être autrement ? Les voitures qui sortent des chaînes actuellement sont fiables à 99,999%, et roulent 200 000 kms au pire.

Heureusement, certains commentaires pointent le fait que, peut-être la raison pour laquelle il y a tant de différence est qu’on ne parle jamais des projets automobiles avortés. Mais combien de prototypes innovants dans les salons qui ne voient jamais la route ? Et qui sait ce qui se passerait s’ils la prenaient ? Dans l’échange à distance entre le patron de General Motors et Bill Gates, devenu mondialement célèbre (voir ici si vous étiez en vacances sur Mars ou pas encore né), le premier se moquait du second en prétendant que si les voitures étaient conçues comme des programmes, elles crasheraient deux fois par jour. Je ne suis pas persuadé que ce ne serait pas le cas des prototypes de salon livrés en grue parce que le constructeur n’est même pas sûr qu’ils peuvent rouler.

Mais vous me direz que les voitures de production atteignent, quant à elle, cette qualité nécessaire pour rouler 200 000 kms sans se planter (à part erreur du conducteur), alors que c’est rare pour un logiciel de ne pas planter. C’est vrai… mais cela n’a rien à voir avec une quelconque paresse des informaticiens ou un manque de maturité de l’industrie informatique comme voudrait le faire croire J. Palermo.

Savez-vous qu’il existe des programmes informatiques qui ne plantent quasiment jamais ? Est-ce que vous pensez que Mars Rover est programmé en Visual Basic ? Que les satellites prennent le risque de mettre en l’air des millions de dollars à cause d’une erreur de programmation ? Savez-vous que la plupart des appareils électroniques modernes fonctionnent en Java ? Quand est-ce que vous avez vu la dernière fois votre machine à laver planter ?

A l’inverse, le crash du Concorde était du à une lame métallique mal fixée sur l’avion précédent. L’explosion de la navette spatiale à la perte des plaques d’isolant ventral. A bien y regarder, dans le domaine aéronautique ou spatial, la dernière fois qu’on a entendu parler d’un accident lié à l’informatique, c’était le crash d’Ariane 5… lors de son vol inaugural… il y a 16 ans…

Alors c’est quoi le problème ?

Tout simple : si on se donne les moyens, on peut faire des logiciels avec le même degré de robustesse que de la mécanique. Et ne me dites pas que je suis partial : je suis à la base ingénieur en Génie des Systèmes Mécaniques, et je travaille dans l’informatique depuis 10 ans. Je connais le pire des deux mondes Sourire.

Or, le problème est que les projets ne donnent qu’un budget limité à l’informatique, et la réalisation s’en ressent. Si on veut de la qualité en informatique, il faut y mettre le prix… Pour revenir à l’échange entre Gates et Welch, aujourd’hui, en informatique, les gens préfèrent majoritairement l’équivalent de voitures qui coûtent 25 dollars et font 1000 kilomètres au litre d’essence. Même si elles tombent en panne une minute par jour. S’ils veulent une garantie d’absence de pannes, ça leur coûtera 1000 fois plus à l’achat et dix fois plus en essence.

Pourquoi est-ce qu’au final, ça coute aussi cher par rapport au reste de la voiture ? Là encore, c’est extrêmement simple : une voiture est composé de quelques milliers de pièces, dont la moitié en mouvement. Un programme informatique, même d’une complexité moyenne, se compose en général de quelques centaines de milliers d’instruction, toutes dépendantes les unes des autres, et réalisant un mouvement à une fréquence qui se chiffrent en millions par seconde. Je serai curieux de voir une voiture fonctionnelle et fiable avec 100 000 pièces en mouvements. Ou même n’importe quelle machine. Si elle existe, elle doit coûter quelques milliards.

Moralité de l’histoire

En informatique comme dans l’industrie, il y a des règles qui s’appliquent pour tous. On a ce pour quoi on a payé… Tant que les clients ne comprendront pas la complexité inhérente de l’informatique, et croiront qu’il suffit d’envoyer des lignes de texte dans un compilateur, ils obtiendront ce qu’ils méritent : du code pas fini… et des plantages.

Posted in Uncategorized | Tagged | Leave a comment

Un petit tour de Glimpse et de log4net

Ca faisait un bon bout de temps que je voulais faire un petit tutoriel rapide pour mettre en avant ce logiciel génial qu’est Glimpse. J’ai eu l’occasion de discuter longuement avec Nik Molnar, qui est un des deux auteurs, désormais embauché par Red Gate (qui est également mon éditeur, d’où la mise en relation), et j’ai été impressionné par sa vision et la qualité de ses idées pour le futur. Je suis persuadé que ça va devenir un outil aussi essentiel que Reflector, par exemple. Vu que ce n’est pas encore un utilitaire connu, et que je n’ai pas vu d’exemple de mise en place en français, je me disais que ça valait le coup de faire un tutoriel très détaillé…

Setup

On commence donc par créer une application web vide dans Visual Studio, de type ASP.NET :

image

On va ensuite utiliser NuGet pour ajouter les références qu’il nous faudra pour ce test :

image

On commence par Glimpse lui-même :

image

Ensuite, log4net :

image

Et enfin, le plugin qui permet de les faire fonctionner ensemble :

image

Le seul fait d’ajouter la référence à Glimpse met en route pas mal de choses dans le fichier web.config, en particulier l’élément glimpse avec l’attribut enabled à true, ce qui permet d’activer le traçage par Glimpse des données serveur à envoyer sur le client.

image

Première utilisation de Glimpse

Pour tester Glimpse seul dans un premier temps, nous allons rajouter une page web :

image

Et dans cette page, nous créons une simple trace de type Glimpse :

image

Quand on lance l’application sur cette page, on voit apparaître une petite icone en bas à droite. Il s’agit de la manifestation côté client de Glimpse.

image

En cliquant dessus, on voit toutes les informations que Glimpse envoie du serveur au client, et qui nous permettent de déboguer aussi facilement, ainsi en particulier que notre première trace :

image

On ajoute log4net

C’est sympa d’avoir de pouvoir mettre des traces dans Glimpse, mais en règle général, on a déjà un mécanisme de gestion des traces dans nos applications, souvent en log4net. Justement, mettons-en en place dans notre application. On commence donc par rajouter un global.asax :

image

Dans ce fichier, on va rajouter ce qu’il faut pour configurer les traces :

image

Dans le fichier de configuration, il faut rajouter la section de configuration correspondant à log4net :

image

En ajoutant log4net en tant que référence, on a aussi automatiquement ajouté la ligne suivante dans le fichier de configuration :

image

Enfin, il faut également créer la section dans laquelle on va configurer le comportement de log4net lui-même :

image

Ceci suffit pour notre test, mais juste histoire de montrer un peu plus comment fonctionne log4net, voici comment on rajouterait des écouteurs sur un fichier, par exemple :

image

Pour tester l’ensemble, il suffit de changer le code de trace dans notre feuille ASP.NET avec une utilisation de log4net :

image

On note au passage la correspondance entre la chaîne “Content” utilisée ici pour catégoriser la trace et les noms qui avaient été donnés aux éléments de type “logger” dans le fichier de configuration plus haut. Il faut qu’il y ait correspondance pour que les traces soient effectivement écoutées.

Testons

Là où Glimpse et son système de plugin sont géniaux, c’est qu’il n’y a plus rien d’autre à faire : le seul fait d’avoir utilise un écouteur log4net du type Glimpse.log4net suffit à ce que le plugin soit mis au courant des traces, et qu’il les passe à Glimpse pour sérialisation et envoi sur le client.

Quand on lance la page, on voit maintenant un nouvel onglet nommé log4net, avec notre deuxième trace :

image

J’espère que ce petit article vous aura montré l’intérêt de Glimpse et de l’utiliser avec les bons plugins. Pour info, ce plugin ne fait qu’un peu plus de 150 lignes, et encore en comptant les commentaires. Voir https://github.com/jchadwick/Glimpse.Log4Net pour le code source.

Posted in .NET | 3 Comments

Le futur de Microsoft d’après fin 2012…

Intéressant article : http://pandodaily.com/2012/10/13/why-the-fall-of-2012-will-determine-microsofts-fate/

Comme d’habitude, il vaut mieux ne pas lire les commentaires, dont une bonne moitié sont biaisés à un point qui donne une idée de l’infini, comme dirait mon pote Eric Sourire. Par contre, l’article est bien argumenté.

Ca va effectivement être intéressant de voir dans les prochains mois si l’approche complètement intégrée Windows 8 / Windows Phone / Windows RT peut bousculer la locomotive Apple sur les smartphones et tablettes. Perso, je ne pense pas être un prosélyte de Microsoft. Je suis MVP, mais je programme aussi en Java et la plupart de mes recherches se font sur des technologies Open Source. Par contre, plus je vois les effets d’un monopole montant (le dernier en date, de plus en plus fort), plus j’ai envie qu’il y ait une alternative puissante à Apple.

A nouveau, je ne pense pas être partial en disant cela : hier, c’était Microsoft justement qui était dans la même position, et IBM avant eux. Microsoft a su sortir de son approche et s’ouvrir (contraint et forcé, mais tout de même intelligemment) à l’Open Source et l’interopérabilité. IBM, en son temps, a réussi brillamment à se remettre en cause de fond en comble, et à passer d’une entreprise de matériel sûre d’elle et vieillissante à une société de services pionnière en R&D. Comme Microsoft avec les procès retentissants et IBM avec la rouste des années 1990, Apple a besoin d’un bon gros réveil brutal pour perdre un peu de son orgueil actuel qui, il me semble, est un des héritages négatifs de Steve Jobs.

Pour en revenir à l’article, le diagnostic est, selon le point de vue qu’on prend, très positif ou effrayant pour Microsoft. Aujourd’hui, Eric Schmidt ne considère pas que Microsoft fait partie des quatre sociétés les plus importantes en informatique. A y bien regarder, c’est peut-être mettre un peu vite de côté l’activité PC, une des principales mauvaises habitudes des startups. En 2000, rien n’avait grâce hors du web, et on voit où ça a mené… Aujourd’hui, le réseau social et le cloud sont portés aux nues (sans jeu de mots), mais la plupart des applications LOB sont encore locales, et le BYOD aurait même tendance à rallonger leur durée de vie. Du coup, enterrer Windows comme le fait le PDG de Google est peut-être un peu rapide.

Windows 8 / Phone / RT a, à mon humble avis, une vraie carte à jouer. Même des gens pourtant peu enclins à saluer les progrès de Microsoft sur l’Open Source ont reconnu que l’ergonomie de WP7 était excellente. Celle de la version 8 le sera encore plus. Pour avoir testé la version 8 de Windows, j’apprécie la fluidité et la performance de l’ensemble, et je suis convaincu que les utilisateurs y feront plus attention qu’à la disparition du menu démarrer (incroyable ce qu’on a pu entendre comme délire sur ce dernier point : si les utilisateurs étaient trop bêtes pour apprécier les changements justifiés, on travaillerait encore en DOS). Windows 8 a le potentiel d’être le nouveau Windows 95.

Une dernière remarque (et là, c’est le développeur qui parle) : programmer en C# / XAML est une partie de plaisir comparé à Objective C. Je sais que pour l’utilisateur final, ça ne change pas grand chose, mais si vous êtes développeur, ça peut être un argument important. Oui, programmer pour l’Apple Store rapporte aujourd’hui plus d’argent. Mais ignorer un marché de plusieurs centaines de millions de machines serait peu intelligent, et surtout le modèle de programmation est à des années lumières en avance. Et je ne parle même pas de la sécurité, domaine sur lequel Microsoft a pris le taureau par les cornes il y a dix ans maintenant. Apple ne l’a pas encore fait, et c’est une faiblesse.

Posted in Retours | Tagged | 1 Comment

Première revue sur Amazon !

Premier commentaire que je reçois sur la page Amazon qui vend la version anglaise de mon bouquin, et c’est positif (4 étoiles) et très détaillé Sourire Yes !

http://www.amazon.com/Practical-Performance-Profiling-Improving-efficiency/dp/1906434824/

Posted in Retours | Tagged | Leave a comment

Comprendre MongoDB depuis C#

Dans la lignée des articles du type “je ne comprends rien, mais je partage quand même” (voir les articles récents sur Async), voici quelques notes sur mon premier contact avec MongoDB. C’est une sorte de test, pour voir si la courbe d’apprentissage peut être rendue plus facile en montrant toutes les étapes de la prise de contact (y compris et surtout les erreurs et incompréhensions) plutôt qu’en expliquant directement le résultat correct.

Du coup, même avertissement que précédemment : ce que vous voyez ci-dessous n’est peut-être pas la bonne façon de faire. Ne vous en inspirez pas pour écrire du vrai code…

Installation

Histoire de faciliter la vie aux très grands débutants en MongoDB, comme moi, je vais détailler fortement les étapes de l’installation d’une configuration fonctionnelle en C#, sous Windows.

Première chose à faire : télécharger MongoDB pour Windows. Vous récupérez alors un fichier .zip, que vous décompressez où vous voulez. L’arborescence suivante est contenue :

image

Dans le premier répertoire, les licences et le README. Dans le répertoire bin, les programmes :

image

Lancement de MongoDB

Dans un premier temps, nous allons utiliser le plus simple moyen de démarrer MongoDB, en lançant monogd.exe. Apparemment, il est possible de lancer MongoDB en tant qu’un service Windows, mais pour nos tests, pas besoin.

Si on lance simplement mongod.exe, on obtient le message suivant :

image

Par défaut, MongoDB va chercher le répertoire \data\db comme repository de ses données, mais plantera si le répertoire n’existe pas. Par contre, on peut le faire pointer à un autre endroit, en utilisant la grammaire suivante :

mongod -dbpath=D:\Projets\MongoDB\data

Là, la console renvoie ce type de message :

Sun Oct 07 18:43:11 [initandlisten] MongoDB starting : pid=20448 port=27017 dbpath=D:\Projets\MongoDB\data 64-bit host=ANTARES
Sun Oct 07 18:43:11 [initandlisten] db version v2.2.0, pdfile version 4.5
Sun Oct 07 18:43:11 [initandlisten] git version: f5e83eae9cfbec7fb7a071321928f00d1b0c5207
Sun Oct 07 18:43:11 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack=’Service Pack 1′) BOOST_LIB
_VERSION=1_49
Sun Oct 07 18:43:11 [initandlisten] options: { dbpath: “D:\Projets\MongoDB\data” }
Sun Oct 07 18:43:11 [initandlisten] journal dir=D:/Projets/MongoDB/data/journal
Sun Oct 07 18:43:11 [initandlisten] recover : no journal files present, no recovery needed
Sun Oct 07 18:43:11 [initandlisten] waiting for connections on port 27017
Sun Oct 07 18:43:11 [websvr] admin web console waiting for connections on port 28017

Les deux dernières lignes nous indiquent le port pour les appels à MongoDB (27017 par défaut) et pour l’administration par la console web (28017 par défaut). Et si on jette un oeil dans le fameux répertoire pointé par l’option, voici ce qu’on y trouve :

image

Conséquentes, les tailles de fichiers, pour une base dans laquelle on n’a encore rien fait ! Mais il s’agit certainement de réservation de taille, comme pour des fichiers MDF…

Driver C# pour MongoDB

La base de données proprement dite étant lancée, on peut passer aux appels en C#. Par contre, il faut pour cela installer le driver, qu’on trouvera ici. Que vous utilisiez le .msi ou le .zip, vous obtiendrez deux librairies .NET qu’il faudra ajouter en référence au projet de test Visual Studio .NET que nous allons mettre en place, à savoir MongoDB.Driver.dll et MongoDB.Bson.dll (dans C:\Program Files (x86)\MongoDB\CSharpDriver 1.6 ou équivalent en fonction de votre système).

image

Le répertoire contient également le fichier .chm avec l’aide, même si le site de MongoDB, et particulièrement la section C# qui nous intéresse, sont très complets et bien réalisés.

Première connexion

Après avoir créé un projet de type console dans Visual Studio et ajouté les deux fichiers susnommés en référence, nous pouvons écrire le code suivant :

image

Il existe d’autres surcharges de MongoServer.Create, qui prennent en paramètre les types suivants :

  • MongoConnectionStringBuilder
  • MongoServerSettings
  • MongoUrl
  • Uri

Comme pour le lancement de la base de données, nous resterons sur le plus simple ici, à savoir la surcharge prenant une chaîne où on écrit la chaîne de connexion la plus simple possible, à savoir mongodb://[serveur]:[port].

Pour travailler dans MongoDB, il faut utiliser une database du server. Le plus simple dans un premier temps est d’utiliser la fonction qui permet de lister les bases de données, en espérant qu’on en trouvera une par défaut :

image

Ou bien, en ajoutant un using System.Linq :

image

C’est bien le cas :

image

Toujours dans le but de garder les choses simples, nous utiliserons cette base de données existant par défaut pour la suite des manipulations de test. Pour récupérer une instance .NET correspondant à cette database, nous utilisons le code suivant :

image

Notion de collection

Dans MongoDB, on parle de collection, car la notion de table est plus proche d’une structuration tabulaire forte, alors que dans MongoDB, on peut entrer des données structurées de manière plus lâche. Il semble qu’on puisse avoir des schémas des documents qu’on entre dans la base, mais qu’il soit possible de dériver et d’entrer des données différentes. Ne me demandez pas pourquoi : je suis en train d’apprendre, comme vous si vous lisez ceci Sourire.

Le contenu de ces collections est constitué de “documents”, stockés sous une forme BSON (Binary JSON). Quand on utilise C#, on peut associer une classe en correspondance avec le contenu d’une collection, ce qui permet d’utiliser plus facilement les données, en lecture comme en écriture. Pour ce premier test, nous allons donc commencer par créer une classe Personne, toute bête :

image

La surcharge de ToString() n’est pas importante, elle nous servira juste pour afficher les résultats des requêtes, si on arrive jusque là pour ce premier article. Pour utiliser une collection basée sur cette classe, nous allons mettre en place le code suivant :

image

Normalement, la fonction Insert devrait nous permettre de rentrer des données dans cette collection annuaire :

image

Ce code compile, mais il faut qu’on fasse quelque chose de plus pour voir si les données sont bien persistantes, à savoir arrêter la base de données, la relancer, et faire ce coup-ci un programme sans les Insert, mais avec une instruction permettant de compter les données :

image

Les ennuis commencent…

Le problème est que cette ligne de code renvoie 1 :

image

Oui, une entrée ! Je comprendrais zéro entrées, ce qui me ferait supposer que j’ai oublié quelque chose comme une instruction de type Commit. Je comprendrais aussi quatre, parce que j’ai rentré quatre données. Mais 1 ! Qu’est-ce qui peut bien faire qu’on a un résultat aussi bizarre ?

Voilà le problème dans le genre d’approche “on fonce dans le tas” que je vous propose de suivre ici : je ne connais rien à la façon dont fonctionne MongoDB, donc quelque chose qu’un habitué va voir comme évident me désoriente complètement…

En cherchant un peu dans la classe collection, je me suis rendu compte ensuite qu’il y avait une fonction Save, qu’on pouvait utiliser exactement de la même manière : c’est étonnant, car en général, une API ne donne qu’une seule façon de réaliser une fonction. Or, on peut écrire le code ci-dessous, et il compile :

image

Histoire de bien repartir de zéro à chaque fois (on enlèvera évidemment cette ligne plus tard), je fais ceci avant chaque nouvel essai :

image

Par contre, à la runtime, ça ne se passe pas bien, contrairement au même programme utilisant la fonction Insert :

image

Le message est un peu plus explicite, et il y a un semblant de logique sur l’obtention d’une seule ligne dans la persistance : comme il n’y avait pas d’Id, peut-être qu’il était créé par défaut, et du coup, les entrées suivantes n’étaient pas prises en compte ?

Un début de correction

Pour tester cette hypothèse, on change un peu la classe Personne :

image

Apparemment, MongoDB doit être basé sur des conventions, car le seul fait de mettre une propriété qui s’appelle Id a suffi pour changer le message d’erreur :

image

Donc, quelque chose a bien reconnu la présence de cette propriété Id, mais il manque un générateur d’Id pour que ça marche. Peut-être que si on met les Id à la main dans les lignes d’insertion, ça ira mieux ?

image

Effectivement, ça va beaucoup mieux, et on a bien désormais 4, comme résultat de la requête sur le nombre de documents dans la collection :

image

Ceci fonctionne d’ailleurs même si on arrête et relance la base de données MongoDB. Ainsi que si on enlève le DropDatabase et les instructions Save, donc la persistance fonctionne également. Cool, on commence à arriver à quelque chose Sourire.

Revenons à l’Insert

Si maintenant on essaie de revenir sur notre premier essai, est-ce que ça marche ?

image

Les résultats sont identiques, et on a bien quatre entrées dans la collection si on requête sur la persistance. Il doit pourtant bien y avoir une différence… Du coup, un peu de recherche sur internet, et on trouve la solution, qui est en relation avec la notion d’identifiant : Save met à jour au fur et à mesure qu’il rencontre le même identifiant, alors qu’Insert ne fera rien dans le même cas.

Du coup, supposons qu’on mette tous les identifiants à la même valeur comme ceci :

image

On a le même résultat qu’au début, à savoir une seule entrée. Pour savoir de laquelle il s’agit, nous ajoutons la ligne suivante, juste après le décompte :

image

Résultat :

image

Si maintenant, on fait la même chose avec un Save à la place d’Insert, voici ce qu’on obtient :

image

Voici la différence : l’Insert a créé dans la base une première entrée avec l’identifiant “a”, puis n’a rien fait sur les autres instances avec le même identifiant, car il était impossible d’ajouter l’entrée (mais étonnamment, MongoDB ne renvoie pas d’exception sur ce cas). Par contre, Save a à chaque fois écrasé la valeur précédente de l’entrée identifiée par “a”, et donc c’est la dernière ligne qui l’a emporté…

Faisons bien les choses

Du coup, le plus logique dans une utilisation normale est de mettre en place l’insertion de données avec la fonction Insert qui va bien. Mais en regardant à nouveau les fonctionnalités proposées, il se trouve qu’il y a un InsertBatch(). Or, la documentation explique qu’il faut utiliser cette fonction pour les insertions en volume, de façon à garder de bonnes performances. On réécrit donc le code comme ceci :

image

Maintenant, il ne nous reste plus qu’à tester une requête un peu plus sympa :

image

Coup de bol : ça marche du premier coup, et on récupère bien toutes les personnes dans la collection dont la propriété Nom a pour valeur Dupond :

image

Conclusion

Ca fait déjà pas mal de choses pour un premier test de MongoDB depuis C#, donc je vais arrêter là… Je vous redonne juste le code complet, qui est finalement très simple :

using System;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;

namespace TestConsole
{
    class Personne
    {
        public string Id { get; set; }
        public string Nom { get; set; }
        public string Prenom { get; set; }

        public override string ToString()
        {
            return string.Format("{0} {1}", Prenom, Nom);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MongoServer server = MongoServer.Create("mongodb://localhost:27017");
            //server.GetDatabaseNames().ToList().ForEach(n => Console.WriteLine(n));
            //server.DropDatabase("local");
            MongoDatabase db = server.GetDatabase("local"); 
            MongoCollection<Personne> annuaire = db.GetCollection<Personne>("annuaire");

            annuaire.InsertBatch(new List<Personne>()
            {
                new Personne() { Id = "a", Nom = "Dupond", Prenom = "Jean" },
                new Personne() { Id = "b", Nom = "Lefebvre", Prenom = "René" },
                new Personne() { Id = "c", Nom = "Dupond", Prenom = "Mathieu" },
                new Personne() { Id = "d", Nom = "Dupond", Prenom = "Sergio" }
            });

            Console.WriteLine(annuaire.FindAll().Count());

            var query = new QueryDocument("Nom", "Dupond");
            foreach (Personne r in annuaire.FindAs<Personne>(query))
                Console.WriteLine(r);
        }
    }
}

A nouveau, ça doit paraitre absolument simpliste à quelqu’un qui connait MongoDB, mais j’espère que cette approche pas-à-pas, erreur après erreur, aidera d’autres débutants à comprendre plus vite.

Posted in Uncategorized | Tagged | Leave a comment

Comprendre Async (deuxième étape)

Contexte

Dans l’article précédent, j’ai déroulé mes premiers tests en Async, histoire de voir si l’apprentissage par l’erreur pouvait aider à comprendre comment fonctionne cette technologie. Nous nous étions quittés sur une question, à savoir s’il y avait plus simple / élégant / recommandé pour réaliser une exécution de code lors de la fin d’un appel asynchrone. La méthode asynchrone renvoyant au final une valeur, nous souhaitions pouvoir par exemple utiliser la valeur pour appeler une autre fonction, sans nécessairement compliquer le code avec des ContinueWith.

On continue de creuser

D’après ce que je lis ça et là sur le sujet, il doit être possible d’écrire cette ligne plus simplement :

image

On va tenter l’écriture avec un await :

image

Problème habituel : on ne peut pas mettre un await sans que la fonction soit déclarée en async (ça commence à rentrer…) et on essaie donc de mettre un async sur le Main, avec comme un vieux doute :

image

Effectivement, ça plante :

image

Ce n’est pas grave : on va juste extraire la méthode (en utilisant la refactorisation de Visual Studio bien sûr) pour la mettre dans une fonction async :

image

On donne le nom d’Appel à la fonction à créer, et on obtient un code qui compile sans erreur :

image

Par contre, il y a quand même un avertissement :

image

Effectivement, si on exécute tel quel, on a toujours le même souci, à savoir que comme on va arrêter la thread Main avant que le message en retour ne soit traité, on ne verra pas la fin du traitement :

image

Pour valider que c’est bien le cas, on ressort notre astuce précédente avec un Thread.Sleep(3000) dans le Main :

image

Le résultat montre que dès le premier affichage de res, on a maintenant une valeur :

image

Du coup, pas besoin de boucler pour attendre qu’il soit différent de la valeur par défaut, et on peut écrire simplement :

image

Mais du coup, on retombe finalement avec ce genre d’appel sur un enchaînement synchrone…

Point à mi-parcours (OK, à 10% du parcours)

En fait, arrivé là, je me demande si le problème ne vient pas de ce que j’essaie de comprendre l’asynchronisme à partir d’une application en mode console, qui fonctionne de façon séquentielle, et donc fondamentalement synchrone. Du coup, je vais plutôt continuer avec une application test Winforms, histoire de voir les effets sur une application qui utilise une pompe de message. L’hypothèse est que, comme l’await dans notre cas revient au comportement synchrone, il doit quand même y avoir une différence, mais elle n’est pas visible…

Quelques semaines plus tard

Arrivé à cette étape, je me suis rendu compte que j’avais besoin de lire de la doc avant de continuer à faire mes tests en aveugle depuis le code, sous peine de ne pas arriver à grand chose. Entretemps, une lecture du blog de Julien Dollon (http://julien.dollon.net/post/Async-is-not-ALWAYS-your-friend.aspx) et un commentaire de sa part m’ont aidé à avancer en partageant l’asynchronisme et la concurrence par les tâches.

Cette différence, fondamentale mais pas si facile à capter, est bien posée dans l’excellent blog de Jérôme Laban, dans la partie 1 de ses posts sur Async. Je vous mets les liens, parce que ce sont trois très bons articles :

http://www.jaylee.org/post/2012/06/18/CSharp-5-0-Async-Tips-and-Tricks-Part-1.aspx

http://www.jaylee.org/post/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.aspx

http://www.jaylee.org/post/2012/09/29/C-Async-Tips-and-Tricks-Part-3-Tasks-and-the-Synchronization-Context.aspx

Le premier lien m’a permis de comprendre qu’effectivement, je ne pourrais pas aller beaucoup plus loin dans la compréhension d’Async avec une application console. L’auteur explique qu’Async ne s’occupe pas de concurrence, mais simplement d’asynchronisme par la mise en place (par le compilateur) d’une machine à état, qui fait progresser les différentes étapes par les mots clés await. Hors, une des difficultés est justement que la synchronisation du contexte ne donne pas la garantie de retomber sur le thread UI, ou sur le thread nécessaire pour que des opérations dépendantes du thread fonctionnent.

Bref, ça conforte l’idée qu’il faut repartir d’un autre exemple avec une interface, ou en tout cas deux threads. C’est d’une certaine manière ce qui a forcé la mise en place de Task dans les exemples précédents, alors que les notions sont séparées.

Cet article a également participé à me faire comprendre qu’Async ne mettait pas fondamentalement en place de la concurrence, car il fonctionne à la base sur un thread.

Quelques notes de plus

En fait, await n’attend pas tout de suite, mais il est le signal que la tâche représentée par la fonction sera considérée comme terminée lorsqu’elle aura fini la commande marquée comme await.

public async Task Initialize()   
            {       
                //Thread.Sleep(500);
                await Task.Delay(500);
            }

Thread.Sleep fait attendre tout le monde. Task.Delay sans await lance un delai, mais on passe 3 ms au final, car la fin n’est jamais attendue. Quand on met un await, on n’attend pas la fin de chaque tâche, mais on donne la possibilité au cas appelant de connaître la fin de ces tâches, bien qu’elles aient été lancées à la suite sans délai. Du coup, on est à 503 ms…

Au programme de la troisième étape

Dans le prochain article sur le sujet, je repartirai d’une application exemple qui va nous permettre de mieux voir le fonctionnement que mon application console, pas adaptée. Pour ceux qui souhaitent comprendre Async, désolé pour ce détour, mais je vous avais prévenu : ces articles ne sont pas des cours par quelqu’un qui connaît, mais un carnet de bord des étapes d’apprentissage de quelqu’un qui cherche à apprendre. C’est du coup plus tortueux, mais j’espère que ça adoucit la courbe d’apprentissage pour un débutant…

En attendant, je vous recommande à nouveau la lecture des trois articles sur le blog de Jérôme Laban. Perso, j’y retourne…

Posted in .NET | Tagged | Leave a comment

Une photo qui fait plaisir !

Tous ces gens qui montrent leur exemplaire de mon livre, franchement, ça me va droit au coeur que Nik Molnar ait pensé à faire cette photo et à me l’envoyer !

image

Nik est un des développeurs derrière l’excellent projet Glimpse, et il donnait il y a quelques semaines sa première conférence pour le compte de Red Gate, sur le sujet de la performance. Red Gate a distribué des exemplaires de mon livre Practical Performance Profiling : Improving the efficiency of .NET code (livre toujours disponible ici).

image

Je vous parlerai dans pas longtemps sur ce blog du projet Glimpse, avec une démo sur des services web si possible. Pour décrire en une phrase ce qu’il fait, je trouvais que le slogan mis en avant sur le site était parfait :

What Firebug is for the client, Glimpse does for the server… in other words, a client side Glimpse into whats going on in your server.

Posted in Performance, Retours | Tagged | Leave a comment

Le Big Data, nouvel effet de mode

Je viens de lire l’interview de Serge Abiteboul dans 01 Business & Techno du 13/09/2012, et je dois dire que je me sens rassuré dans mon opinion sur le Big Data par ce qu’un grand esprit comme lui décrit : le Big Data comme un effet de mode. Je renvoie également à son excellent article de blog sur Big Data.

Sans avoir la prétention d’arriver à la cheville d’un spécialiste de la donnée comme lui (Stanford, INRIA, Académie des Sciences), le fait de travailler depuis dix ans pour une entreprise spécialisée dans l’analyse intelligente de donnée, ainsi que d’avoir écrit un bouquin sur le sujet, me donnent suffisamment de confiance pour donner un avis polémique.

Statistiques commerciales

Il y a quelques semaines déjà, je m’étais posé la question d’une possible mise en avant pour des raisons commerciales, en lisant dans plusieurs magazines cette information :

70% des entreprises françaises n’ont pas d’initiatives ou de réflexion sur le Big Data

Personnellement, je ne trouvais pas l’information pour le moins choquante : j’avais plutôt dans l’idée que 10% des entreprises françaises pouvaient avoir un réel avantage à utiliser des approches Big Data. Alors, savoir que 30% s’y intéressait, ça me paraissait déjà limite trop… Plus tard, en cherchant un peu dans les sources, je me suis rendu compte que le sponsor de l’étude était EMC, un des spécialiste du stockage, et donc fortement intéressé à l’expansion de Big Data pour vendre plus de machines. Ca a achevé de me convaincre de l’inutilité de cette statistique (pourtant joyeusement reprise en chœur par ci par ou encore ici).

Approche technique discutable

Voici, sous forme d’histoire, la façon dont je pense que le Big Data a pris de l’ampleur : il y a encore une décennie ou moins, les analystes des données voyaient les machines croitre au fur et à mesure de la taille de leurs données. Lorsque les bases se mesuraient en To, des serveurs embarquaient plusieurs disques durs. Plus tard, lorsque les tailles sont passées au Po, ce sont des machines, voire des architectures spéciales, qui sont apparues pour traiter tout ça, donnant ce genre d’horreurs :

image

Source : http://fr.slideshare.net/msitpro/sql-server-parallel-data-warehouse

J’ai pris l’approche Parallel Data Warehouse de Microsoft, mais il est évident que j’aurais pu montrer l’Exascale d’Oracle avec la même opinion à la clé : il s’agit d’architectures matérielles démentielles, réalisées principalement dans le but de flatter l’ego parfois démesuré de certaines DSI, et (pas tout à fait accessoirement) de les détrousser au passage Sourire.

Lorsqu’une personne à peu près censée dans leur équipe leur fait remarquer qu’avec un budget divisé par cent, on pourrait obtenir les mêmes résultats à condition que les analystes patientent trente secondes au lieu de trois, ces personnes rejettent en général l’importun d’un commentaire dédaigneux. Typiquement quelque chose attenant à sa compréhension limitée des problématiques fabuleuses auxquelles notre DSI a le courage de s’attaquer…

Mais revenons à notre histoire. Une fois passée cette période de montée en puissance sur des architectures unifiées, les analystes (qui en veulent toujours plus) ont demandé à passer à l’exaoctet (Eo). Et là, un mur… Un peu comme lorsque les développeurs, habitués à avoir toujours plus de vitesse de CPU, se sont rendus compte un jour que pour avoir plus de puissance, attendre le nouveau processeur avec une fréquence plus élevée ne suffirait plus. Il allait falloir coder en multithread. Et c’est beaucoup plus dur…

Pareil pour la donnée : au lieu de tout traiter sur des architectures centralisées à plusieurs millions de dollars, le prochain eldorado serait de paralléliser massivement les analyses, avec des dizaines de machines puissantes. Les vendeurs se sont bien évidemment abstenus de préciser que de simples PC, en nombre plus important mais au final bien moins chers, suffiraient, mais c’est une autre polémique. Seulement voilà, là aussi, ce n’était pas aussi facile. Il allait falloir changer de technologie. Impossible de continuer avec SQL et les bons vieux cubes OLAP. Il allait falloir passer à la vitesse supérieure.

Pour continuer avec notre parallèle sur le développement multithread, la solution est venue des approches de type Map / Reduce : on modifie le traitement pour qu’il s’applique de manière unitaire, et on trouve un algorithme permettant de recomposer les résultats. Ainsi, on peut augmenter à peu près linéairement la puissance de traitement (en volume en tout cas) en augmentant le nombre de nodes impliqués. Donc, plus de limite…

Des analystes ? Pour quoi faire ?

C’est à ce moment précis que tout ça a tourné à la catastrophe. Pour bien appréhender le phénomène, il faut comprendre le mot de Peter Norvig, Chief Scientist chez Google :

We don’t have better algorithms than anyone else. We just have more data.

C’est le nerf du problème : au lieu d’avoir à réfléchir à la façon de traiter la donnée, le surcroit de puissance qu’apporte Big Data permet de trouver des patterns dans un énorme volume sans même avoir à élaborer conceptuellement une requête. Lorsqu’on utilise Big Data pour analyser des logs de serveurs à la recherche d’une intrusion, par exemple, on n’effectue pas une requête précise sur un comportement donné (je veux savoir quand une personne a entré trois mauvais mots de passe à la suite, le tout sur deux serveurs), mais plutôt sur des ensembles flous, quitte à avoir du retraitement derrière (je veux remonter les fréquences de mauvais mots de passe atypiques).

Evidemment, cette perte de contrôle se paie un jour, et pour moi, c’est la raison pour laquelle Big Data est un phénomène de mode : il faut de toute façon de bons analystes derrière. Big Data a simplement rendu possible l’exécution de requêtes inimaginables auparavant, par le fait qu’une puissance énorme est aisément mobilisable (avec un coût en ressources à l’avenant, mais j’y reviendrai). Mais le problème demeure, aussi solide que le mur de la programmation multithread : c’est dur… Et les résultats ne sont pas transformables en réelle valeur sans analystes.

Dans un article, on parle d’ajouter un V comme Valeur aux trois V traditionnels du Big Data, à savoir Volume, Vitesse et Variété des données. N’est-ce pas révélateur ? La première approche du Big Data a été purement technique, et aujourd’hui, les analystes annoncent des manques criants en analystes “Big Data”… Rien que de très logique : on se rend tout simplement compte, après le peak of expectations dans le langage Gartner, que sans analystes pour utiliser l’outil Big Data, il n’y a pas de valeur à en tirer.

La minute Desproges

Attention, ne me faites pas dire ce que je n’ai pas dit ! Je ré-écoute tout Desproges en ce moment, alors je ne peux pas m’empêcher d’utiliser ses phrases clés Sourire. Bref, Big Data a des utilisations spécialisées dans lequel cette approche réalise des traitements impossibles à faire autrement. Cependant, non seulement ceci n’est pas nouveau (les bons analystes savent paralléliser leurs recherches au niveau conceptuel et non technique, et ce depuis longtemps), mais en plus c’est très loin d’être un outil générique. De la même manière qu’hormis la gestion des logs, des transactions, l’Aspect Oriented Programming n’a jamais réellement percé alors qu’au moment de son lancement, il était vu comme potentiellement révolutionnaire, le mouvement Big Data restera, à mon avis, cantonné à des niches spécialisées comme l’analyse de comportements (tests d’intrusion, comportement sur les réseaux sociaux, etc.).

Conclusion

Et l’écologie, dans tout ça ? Il y aurait à dire, là aussi, mais comme ce n’est pas le sujet principal, je me permets de vous renvoyer à un autre article.

image

Mais pour revenir à quelque chose de plus pratique : avant de mettre en oeuvre un projet Big Data pour analyser vos volumes de données hétérogènes, posez-vous tout simplement la question de comment vous feriez si Map / Reduce n’existait pas. Serge Abiteboul conseille de se demander en tout premier si une machine avec beaucoup de mémoire ne suffirait pas. Je ne peux que le seconder sur une approche simple et “to the point”, surtout lorsqu’elle rejoint l’approche NoSQL / Object Prevalence que j’affectionne (voir les multiples billets sur le sujet dans ce blog).

Dans de nombreux cas, une première passe de mise au propre de la donnée peut également permettre de s’en tirer avec une architecture centralisée (et donc de rentabiliser cet Exascale qui vous a coûté un rein pour le matériel et un bras pour le logiciel). De plus, avez-vous réellement besoin de ce temps de traitement de trois secondes ? Oui, ça permet à votre analyste de faire 10 fois plus de requêtes dans une heure de travail… mais avez-vous besoin de quelqu’un qui lance 100 requêtes au hasard, en espérant trouver quelque chose d’intéressant, ou plutôt de quelqu’un qui va réfléchir 58 minutes, puis lancer deux ou trois requêtes bien ciblées ? Si vous avec choisi la seconde alternative, pensez-vous vraiment que les trente secondes gagnées valait le coup ?

Posted in Uncategorized | Leave a comment

Renouvèlement MVP !

<messageperso mode=’autosatisfaction’>

Je suis renouvelé Microsoft Most Valuable Professional, catégorie Connected Systems Developer ! Yes !!! Je pense que les deux bouquins parus cette année sur les performances en .NET chez SimpleTalk et PowerPivot à l’ENI ne sont pas étrangers à la poursuite de cette aventure, mais j’aime à penser que ce blog y participe également ! J’ai de plus en plus de retours sur les articles que j’y publie, et ça me fait très plaisir. Ce titre de MVP ne fait que me motiver encore plus à vous préparer des articles de qualité.

</messageperso>

Posted in Uncategorized | Leave a comment