Liens de la semaine 51-2014: ce que j'ai retenu cette semaine.
Projets:
famo.us: 'THE ULTIMATE WEB PLATFORM FOR DEVELOPERS AND DESIGNERS'Ce framework javascript permet de développer des applications web avec un rendu digne des jeux vidéos : 60 FPS (Frame per Second) et quelque soit le support.( PC / mobile)
tanagra: outils de data mining. Un dispositif concurrent de l'écosystème 'R'. Le langage R est plutôt orienté statistique.
io.js : fork de Node.js, un drame ? non une chance de plus pour cette technologie
Pour continuer dans le sillage de la gestion de projet Agile, voici un nouveau phénomène adopté par de plus en plus d'entreprise: le devops.
Dans ce dispositif, des développeurs (dev) et des exploitants ( (ops du mot anglais operations = exploitant) sont regroupés dans une véritable task force. Ce concept existe depuis environ 5 ans. Ce qui est nouveau, c'est engouement qu'il connait auprès des entreprises comme: google, Amazon, Bouygues, free etc.
ex :
Ce mode de fonctionnement est le quotidien des petites structures (PME ?) avec des équipes informatiques réduites. Son introduction dans des grands groupes est quelque part un constat échec.
Le devop permet de capitaliser sur une démarche Agile en amont.
Le devop n'est pas un 'facilitateur' ou un interlocuteur privilégier vis à vis de l'exploitation: Il est exploitant à part entière. Cette compétence vient en complément avec sa maîtrise du développement.
Dans cette configuration, la task force aura la responsabilité du projet de la conception à la mise en production. Ce système est en contradiction avec les bonnes pratiques (ex: ITIL) qui recommandent un cloisonnement entre le développement et la production. En effet les deux entités poursuivent des objectifs contradictoires: le développeur produit du changement (nouvelle version, fonctionnalité) alors que l'exploitant est le gardien de la stabilité: les applications ronronnent sagement.
Séduisant sur le papier mais difficile à mettre en place.
La mise en place d'un tel dispositif n'est pas facile: on touche ici à des sujets d'organisation avec une remise en cause des pratiques.
Au lieu d'utiliser le langage natif d'arduino, on installe un programme 'firmata' qui permet de dialoguer avec un programme en javascript tournant sur un PC.
Johnny-five propose deux modes d'utilisation:
En interractif: REPL :Read - Eval - Print - Loop. C'est l'équivalent d'un interpréteur de commande.
(voir exemple dans mon post cité plus haut).
Soit en mode autonome: Le programme se déroule sur le PC et envoie ses instructions sur l'arduino.
Maintenant comment piloter son arduino depuis Internet, son smartphone , un site WEB .. ?
Le montage était destiné à piloter un laser pour distraire un chat (et moi par la même occasion)
Nous devons introduire un dialogue supplémentaire entre le PC et le robot. Ce dialogue utilisera le protocole MQTT: Le protocole des 'choses' reliées à Internet.(MQ Telemetry Transport) MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol.
Ce protocole est très léger et il connu par la plupart des objets connectés. Et son domaine d'utilisation s'est élargie au transport de message pour les Tchats.
Pour mémoire, Facebook utilise MQTT pour sa messagerie instantanée (ici un lien sur l'histoire de MQTT)
Pour le mettre en place , il faut disposer d'un serveur MQTT et des clients.
Pour le serveur, mon choix s'est porté sur MOSCA. C'est un serveur MQTT en javascript propulsé par le réacteur Node.js
Lien ici.
Mosca vous permet de construire votre propre serveur MQTT.
Mon code pour le serveur est le suivant:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Le serveur utilise un bakend pour stocker les messages dans mon exemple j'utilise une base NoSQL MongoDB.
Le serveur se teste facilement avec un outil en ligne de commande: mosquitto
(MQTT est protocole de type : PubSub : publier , souscrire) mosquitto_sub -t 'hello/you'
mosquitto_pub -m "c est moi" -t 'hello/you'
Le schéma général est le suivant:
réalisé avec http://shaky.github.bushong.net/
La partie web est en mode REST
Trois motifs sont utilisés pour décoder es URL , un pour l'axe des X , un pour l'axe des Y, le dernier pour allumer ou éteindre le laser.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
C'est l'histoire du développeur COBOL qui a fait fortune avec les maintenances liées au passage à l'an 2000. Avec son argent, il décide de se faire cryogéniser (congeler) et de tomber dans un sommeil (presque) éternel.
Un jour quelqu'un le met au micro-onde et le réveille. Le développeur COBOL ouvre les yeux et demande: pourquoi vous me réveillez ? . L'autre lui répond: on est en l'an 9999 , on fait comment pour le COBOL ?
Ces deux projets proposent une implémentation en couche un peu à la mode MVC à destination des microcontroleurs
Nous avons parlé aussi du protocole MQQT qui permet de construire des dialogues de machine à machine. Ce protocole est basé sur le mode publish-subscribe et il est utilisé aussi pour les programmes de 'chat' (exemple facebook messenger)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Mais ce n'est pas la bonne manière vraiment utiliser la combinaison javascript / arduino. L'idée est de piloter en temps réel l'arduino au travers d'une interface web. La pile est donc: express, mqqt pour la partie web et johnny-five et mqqt pour la partie robot. A tester !
Pour faire une suite voici quelques manipulations avec le client mongo ou l'API Ruby.
Pour commencer:
Avec le client mongo :
voir toutes les bases : shows dbs
voir toutes les collections d'une base: show collections
Pour les recherches :
Rechercher à l'aide d'une expression régulière :ATTENTION à réserver que pour les champs 'string'
Toutes les stations de velib dont l'adresse contient le mot 'filles' (ex filles du calvaire ) db.stations.find({address :/.+filles.+/i}).count()
ou en version moins compacte : db.stations.find({address : $regex :{/.+filles.+/i}}).count()
Pour inverser la sélection : $regex :{/(?!.+filles.+)/i}
Rechercher les entrées avec qui n'ont pas un champs précis: db.stations.find({rem: {$exists : false}}) ou db.stations.find({rem: null}) # cette forme ne fonctionne pas si un champs contient la valeur null
Avec l'API Ruby:
rech = @stations.find({:arrondissement => nil})....
Afficher que certain champs en sortie: db.stations.find({arrondissement: 75001},{'state.total_slots' : 1})
(le champs id ou _id est special ,c'est l'identifiant des entrées. il est toujours retourné sauf si , la valeur de sa clé est mise à zero.)
Une recherche avec une condition qui porte sur deux champs de l'entrée (utilisation de $where et this.
(API Ruby) @alerte = @coll.find('$where' => "this.reel['total moe'] >= this.valide['total moe']" , 'semaine' => semaine )
Enfin: un tri
db.stations.find({},{address:1}).sort({'state.total_slots' :-1 }).limit(1)
Ici , le tri combiné à limit(1) permet de récupérer la valeur la plus grande.
Regroupement d'entrée:
Le plus simple est l'opérateur distinct:
db.stations.distinct('arrondissement')
distinct retourne un array (tableau) , aussi pour connaitre le nombre d élément: db.stations.distinct('arrondissement').length
L'operateur group:
Un autre manière de déterminer le maxima d'une série
un autre exemple avec le client mongo db.stations.group({initial : {cmax : 0 } ,reduce : function(obj,prev) { if (obj.state.total_slots > prev.cmax) prev.cmax = obj.state.total_slots }})
[ { "cmax" : 72 } ]
Enfin un exemple de regroupement avec cumul intermédiaire et condition :
Dans cette video et dans les slides , une présentation de la gestion des vues dans angularjs.
C'est la technique de base pour réaliser des SPA (application d'une seule page)
Pour cela , il faut récupérer l'extension angular-route sur le site d'angularJS.
Le code est simple:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
J'étais parti pour faire une video sur AngularJS mais j'ai éprouvé la nécessité de remettre cette technologie dans un cadre plus général de développement des applications.
J'expose le système courant du templating coté serveur et coté client.
Templates coté client
Avec ici la synthèse:
Mais le plus important est de replacer le phénomene des SPA: Single Page Application dans le contexte. REST , MVVM (angularJS ) , SPA et NoSQL sont autant des pièces d'un même puzzle.
Pourquoi des applications de ce type:
Pour des raisons Economiques: les coûts sont partagés , elles sont scalables, elles sont simples.
Pour la simplicité des solutions misent en oeuvre.
Au premier abord toutes ces notions semblent très compliquées, mais en commençant doucement par des exemples simples, tout devient possible.
En conclusion: ce n'est pas un simple mouvement de mode. Ces évolutions touchent la manière de faire des applications, de conduire des projets.
La vague REST va déferler sur nous. Hélas, la encore des marchands de rêve vont chercher à vous vendre du REST au kilo.
Ce qu'il faut bien comprendre: Les architectures REST devront être une CONSÉQUENCE de l'évolution de vos applications et non pas une CAUSE d'évolution de celles-ci.
En clair: commencer par mette du REST sans avoir ce qui va avec, mettra en difficulté votre système informatique, vos équipes etc.
«Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000.»
C'est un livre de chevet (publié en 2007) :lien ici
Couverture ( observez qui à donné son avis sur le livre)
(selfie truqué : pourquoi ? : à vous de trouver l'erreur)
C'est une série de principe :
1) Utilisation des verbes (Méthodes) du HTTP.
GET : lire une ressource
DELETE : supprimer une ressource
POST et PUT: pour creer ou modifier une ressource
(ou inversement : l'idée est d avoir un verbe pour créer différent de celui utiliser pour modifier)
2) Chaque ressource a son URL. On interagit avec les ressources en combinant les url avec les methodes HTTP.
GET http://www.example.com/customers/12345
GET http://www.example.com/customers/12345/orders
GET http://www.example.com/buckets/sample
PUT http://www.example.com/customers/12345
PUT http://www.example.com/customers/12345/orders/98765
3) Pas de session gérée coté serveur : Toute l'information de session est stockée sur le client ET donc chaque requête est autonome et complète.
4) Le serveur applicatif ne sert qu'a délivrer de la donnée (le plus souvent au format JSON et non plus XML)
Voila le rapidement présenté le REST.
Pourquoi le REST a-t-il le vent en poupe ?
Il permet de répartir les coûts d'infrastructure entre le fournisseur de ressource (service) et l'utilisateur (poste client). Il est donc pleinement compatible avec le modèle économique des clouds. Les traitements coûteux en CPU (assemblages des pages WEB, manipulation des donnée) sont réalisés sur la machine du client.
Les infrastructures et les applications sont plus simples: pas besoin d'avoir des serveurs de session, des bus d'entreprise etc.
La scalabilité est linéaire: sans partage de session à prévoir, avec des serveurs à gestion d 'événement (Node.js , nginx) , l'ajout d'un serveur augmente surement le nombre de connexion possible.
Il met fin au débat entre les langages et les framework : PHP ,Java, Spring, Express, Rails :La partie serveur ne sert qu'a délivrer de la donnée JSON. Le seul langage à maîtriser vraiment est le Javascript (le seul langage universel pour le navigateurs). Aussi, si vous n'avez pas les ressources de développement aguerries au Javascript l'adoption du REST sera difficile.
Aussi mettre en place du REST sans avoir un idée de la stratégie à mettre en place coté client (Angular, Backbone , Ember ?...) c'est prendre le sujet à l'envers.
Comment reconnaître le vrai du faux REST.
Le critère de la session gérée coté client est important, sinon le simple test suivant est suffisant :
Est ce que votre application fonctionne avec le simple client HTTP en ligne de commande CURL ?
Ex : curl -X DELETE http://localhost:4567/pgm/5352d84751514034cc000048
(la partie serveur qui répond à la requete)
## Restful uri
##
delete '/pgm/:id' do
@id_pgm = params[:id]
@pgm = @db['pgm'].remove('_id' => BSON::ObjectId(@id_pgm) )
response.write ("{ok}")
end
Pendant de nombreuses années le XML tenait le haut du pavé dans le domaine de format de fichier: pour les données , les configurations etc. Le XML était partout:
Depuis, on revient à un usage plus raisonnable du XML. Et des formats comme le JSON, le YAML ont maintenant trouvés leur place.
Comment stocker efficacement des fichiers XML ?.
La solution habituelle.
La solution basique consiste à extraire les informations pertinentes du XML pour les sérialiser dans une base de données. Le format XML se prête mal a des opérations de recherche.
Cette solution à ses limites surtout pour des enregistrements XML de taille variable. L'exemple qui vient à l'esprit est celui de la récente réforme des échanges bancaires: le SEPA.
D'un format fixe de 240 caractères , les nouvelles normes ont évoluées sur des articles XML de taille variable. Le volume est plus important en raison de l'utilisation du XML, du détails des opérations mais d'une taille non prédictible.
Des solutions à base de NoSQL.
Le principe de ces solutions est de stocker les fichiers XML échangés dans une base de donnée Nosql. Le choix de cette base se portera sur un dispositif orienté document comme MongoDB.
Les informations seront stockées sous deux formes:
Sous la forme d'origine en XML et sous un format JSON avec une succession de clé / valeur. Les opérations de recherche se feront sur la partie JSON.
Ci-dessous un exemple de programme en Ruby utilisant la librairie nokogiri pour parser le XML:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Le fichier XML est exploré récursivement puis injecté dans une base NoSQL mongoDB par ce script:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ainsi l'information sera disponible sous deux formes avec une des formes autorisant des recherches multicriteres. Le stockage dans un système sans schéma est particulièrement adapté à des informations hétérogènes.
Lors de la mise en place d'architecture à base de Node.js, les mêmes questions reviennent:
Comment superviser des applications sous node.js ?
La réponse habituelle est FOREVER : forever permet de lancer un programme sous node.js et de le relancer si besoin.
Sur une machine multi-processeur, il est fréquent lancer plusieurs instances de l'applications sous node.js.
Node.js étant monoprocesseur (monothreading) il restera cantonné sur un CPU.
Je lance donc plusieurs instances de node.js (1 par CPU) par la commande forever.
Dans le cas où on dispose de plusieurs serveur (physique ou VM ) , il est d'usage de placer un serveur web NGINX en frontal qui fera office de reverse proxy.
Se pose alors le problème de supervision générale du système.
Pour ma part, je lance un 'agent' sur chaque serveur qui renseigne en temps reel sur les instances Node.js qui tournent sur un serveur.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ce programme en coffeescript lance la commande forever avec l'option list (lignes 22 à 28) et 'compte' le nombre de ligne retournée (lignes 9 à 19) .
Ce dispositif accessible par une API REST (lignes 30 à 35 )permet de construire des interfaces graphiques de supervision:
Avec le résultat suivant :
Tout ceci est à faire manuellement.
Est ce que je suis le seul à avoir ces problèmes ?: NON répond Hongli LAI à la conférence Dot.js de Paris: (video sur ce lien )
Il reprend les différentes étapes de construction d'un projet Node.js
forever forever...
Puis faire démarrer le tout
Mettre en serveur Nginx en reverse proxy
Mettre plusieurs instances en cluster
Et monitorer l'ensemble
Ces dispositifs sont utilisés chez quelques PME :Apple, Pixar, New York Times, AirBnB, Juniper etc.. et over 350.000 websites.
Ce montage en couche peut être remplacé par 1 seul composant : phusion passenger
phusion passenger fournit les informations suivantes:
Lancement des Node.js : phusion passenger se charge de lancer le nombre d'instance qu'il faut et d'équilibrer leur charge.
Reverse proxy
Supervision: à la place d'une supervision à programmer , la ligne de commande phusion passenger retourne les informations suivantes.
$ passenger-status
Version : 4.0.37
Date : 2013-11-14 21:55:30 +0100
Instance: 25002
----------- General information -----------
Max pool size : 6
Processes : 1
Requests in top-level queue : 0
----------- Application groups -----------
/Users/phusion/nodetestapp#default:
App root: /Users/phusion/nodetestapp
Requests in queue: 0
* PID: 25012 Sessions: 0 Processed: 2 Uptime: 9s
CPU: 0% Memory : 14M Last used: 3s ago
Phusion passenger fonctionne soit tout seul , integré avec nginx ou encore avec apache.
Avec Node.js les architectures sont encore plus simples , plus performantes plus robustes et moins chères.