mercredi 16 octobre 2013

Wercker


Build and deploy
#dartlang #continuousdelivery

Wercker est une plateforme de déploiement continue qui permet de builder et de déployer des applications. Depuis peu il est possible de l’utiliser pour builder des applications Dart !


En effet, Wercker est une plateforme ouverte, il est donc possible de définir une box, c’est-à-dire, la stack sur laquelle lancer le build. Ici la box Dart a été créée par un employé de l’entreprise, +Pieter Joost van de Sande, aussi auteur du plugin Dart sur Sublime Text 3. Il n’y a pas encore de step spécifique Dart mais il est très facile de configurer son projet pour le builder. Il suffit d’ajouter un fichier wercker.yml à la racine avec :

  box: wercker/dart
  build:
    steps:
      - script:
          name: build
          code: |
            pub install
      - script:
          name: test
          code: |
            dart --checked tool/hop_runner.dart test

Il ne reste plus qu’à déployer sur l’une des plateformes que propose Wercker, Heroku étant une possibilité grâce à l’Heroku Buildpack Dart (https://github.com/igrigorik/heroku-buildpack-dart)

jeudi 3 octobre 2013

Event Loop

Tournez manège !
#dartlang #eventloop

L’asynchronisme dans Dart est présent quasiment partout dans le SDK. Une bonne partie des fonctions retournent des futures ou des streams dès que l’on utilise l’I/O, les events du DOM, ou bien encore les Timers. Il est donc nécessaire d’avoir une architecture pour exécuter ces événements en asynchrone, à savoir une boucle d’événements (event loop). L’article suivant décrit sont fonctionnement :


Ce qu’il faut retenir :
  → Cette architecture s’applique à la fois pour les applications qui tourne sur la VM (standalone ou embarquée dans Dartium), que le code compilé en JavaScript par dart2js
  → Le code Dart s’exécute dans un seul Thread (pour exécuter du code en parallèle, cf. les Isolates ou les WebWorkers)
  → Il existe deux fils d’exécution dans la boucle d'évènements
    ↳ L’event queue qui contient tous les événements extérieurs dont l’I/O, les events du DOM, les Timers, les messages entre Isolates, etc.
    ↳ La microtask queue qui ne contient pour le moment que des tâches qui viennent du code Dart. Cette queue est nécessaire car le code répondant à un événement a parfois besoin de s’exécuter plus tard mais avant l’événement suivant.
    ⇒ Donc la microtask queue a priorité sur l’event queue !

Comment ajouter un événement ou une tâche dans ces queues :
  → new Future() et new Future.delayed() ajoutent un event dans l’event queue.
  → runAsync() ajoute une tâche dans la microtask queue

Ce qu’il faut savoir sur les Futures :
  → La fonction passée à la méthode then est exécutée immédiatement après que le Future se termine. Sauf lorsque le Future est déjà terminé, alors une tâche pour exécuter la fonction est ajoutée à la microtask queue.
  → Faire future.then((_) {new Future(...)}) pour lancer le code qui doit suivre en asynchrone, en l’ajoutant  dans l’event queue.

Les dernières recommandations :
  → Dans la majorité des cas, préférer ajouter un événement dans  l’event queue.
  → Conserver la microtask queue aussi petite que possible pour ne pas squeezer l’event queue.
  → Pour les longs processus, utiliser plutôt les Isolates ou les WebWorkers pour une exécution en parallèle.

lundi 30 septembre 2013

Optimisation dart2js

L’optimisation qui tire plus vite que son ombre
#dartlang #javascript #dart2js

+Kasper Lund a dévoilé la dernière optimisation du compilateur Dart vers JavaScript, dart2js. Cette optimisation a permit de gagner 13% de performance sur le benchmark Richards, grâce à une astuce découverte par +Nicolas Geoffray, un français de l’équipe Dart :)

Attention, l’explication est compliquée !
L’astuce concerne l’appel d‘une méthode qui a été inlinée dans le code JavaScript généré, sur un objet qui peut être null. Il est nécessaire d’ajouter une vérification pour avoir la bonne exception. Dans l’hypothèse où l’on connaît le type de l’objet o, l’appel Dart suivant :
  o.foo();
donnait en JavaScript :
  o.foo;  // Permet de vérifier la nullité de l’objet.
  <<contenu de la méthode inlinée>>

Ainsi, on obtenait la bonne exception si l’objet o était null donc tout allait bien. Sauf lorsque le tree shaking, qui a pour rôle d'enlever le code non appelé pour alléger le code généré, enlève la vrai méthode o.foo(). Le moteur JavaScript a horreur des propriétés qui n’existent pas sur un objet, ça ralenti l’évaluation de ce code. Du coup, au lieu de vérifier la nullité en vérifiant la méthode foo, on va vérifier sur une méthode qui existe dans tous les objet, à savoir, toString.
  o.toString;  // Permet de vérifier la nullité de l’objet.
  <<contenu de la méthode inlinée>>

mercredi 25 septembre 2013

PostgreSQL en Dart

DB or not DB?
#dartlang #postgresql 

+Thomas Pedersen a tenté d’explorer les possibilités pour communiquer avec une base de données PostgreSQL à partir de Dart. Il fait part de son expérience et a partagé son code.

Il a bien sûr commencé par installer un package indispensable, postgresql :
  dependencies:
    postgresql: 0.2.8

Deuxième étape, il s’est connecté à la base de données, c’est simple et c’est en asynchrone :
  var uri = 'postgres://username:password@localhost:5432/dbname';
  
  connect(uri).then((Connection connection) {
    // Queries...
    connection.close();
  });

Enfin, il a lancé ses requêtes, aussi en asynchrones :
  final String query = "SELECT id, firstname, lastname, height FROM person";
  connection.query(query).listen((row) {
    print("(${row.id}) ${row.firstname} ${row.lastname} - ${row.height}m");
  });

  final String query = “INSERT INTO person (firstname, lastname, dateofbirth, height) VALUES ('$firstname', '$lastname', '$dateOfBirth', $height);";
  connection.execute(query).then((rowsAffected) {
    print("Rows Affected: $rowsAffected");
  });

Il a été surpris par la simplicité d’utilisation de la librairie. Celle-ci profite des possibilités du langage dynamique tel que l’accès direct aux colonnes mais aussi de l’exécution des requêtes en asynchrone grâce à l’utilisation de Future et de Stream. Elle propose d’autres fonctionnalités dont la gestion de paramètres pour les requêtes et la gestion d’un pool de connexion.

jeudi 12 septembre 2013

Dart JSONP


Ou comment contourner CORS
#dartlang #jsonp

Pour faire une requête XmlHttpRequest (HttpRequest en Dart) sur un autre domaine, on est souvent confronté à une restriction de sécurité dénommé CORS, Cross-origin resource sharing. Elle a pour but d’éviter de charger des données d’un serveur autre que celui hébergeant l’application qui n’a pas les bonnes permissions. Cette fonctionnalité est supportée par la majorité des navigateurs modernes, cependant, la plupart des serveurs ne définissent pas les entêtes nécessaires pour le bon fonctionnement de ces requêtes. Du coup, la communauté javascript a inventé un système de contournement : JSONP.

Le principe de JSONP est de charger l’url via une balise script ajouter dynamiquement. Il n’y a plus les mêmes vérifications sur des domaines différents, c’est ouvert.
  <script type="application/javascript" src="http://server2.example.com/Users/1234"></script>
Mais comment savoir quand la requête est terminé et surtout comment récupérer les données ?
C’est la magie de la méthode sioux, on va indiquer un callback à appeler et le serveur va générer le javascript qui va bien pour appeler cette méthode :
  <script type="application/javascript" src="http://server2.example.com/Users/1234?jsonp=*parseResponse*"></script>
Et le serveur retourne par exemple :
  parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
On a donc une faille de sécurité monstrueuse si le serveur qu’on appelle n’est pas sûr : il peut exécuter n’importe quel code javascript !

C’est possible d’utiliser ce principe en Dart, grâce au package _jsonp_ et à la librairie sous-jacente, js-interop. 

L’utilisation est assez simple :
  Future<js.Proxy> result = jsonp.fetch(uri: "http://example.com/rest/object/1?callback=?");

  result.then((js.Proxy proxy) {
    print(proxy.data);

    // It is important to release the data!
    js.release(proxy);
  });

Cette technique d’ajout d’une balise script ne fonctionne pas en pure Dart. Par contre, après quelques essais j’ai réussi a chargé du code Dart sur un autre domaine grâce à la méthode spawnUri. Les serveurs n’ont plus qu’à s’adapter pour générer du Dart !

lundi 9 septembre 2013

Polymer Toolkit


Tout le nécessaire pour débuter avec Polymer.dart
#dartlang #polymer

Lors de mes essais avec Polymer.dart, je me suis heurté à quelques problèmes, d’une part à cause d’une documentation obsolète liée à WebUI, le précurseur de Polymer, mais également du fait que Polymer est encore en phase de développement et que certaines fonctionnalités manquent encore à l’appel ou sont bugguées.

L’équipe Dart a publié très récemment une page dédié à Polymer.dart. C’est un bon début pour commencer avec quelques exemples de custom element, de binding et de templates. Cette page donne également les liens vers les sources et le support.

Pour compléter cette page, rien de mieux que des exemples. +Seth Ladd en a crée de nombreux :
Les tutoriaux “A Game of Darts” et leurs exemples sont progressivement mis à jour vers Polymer. C’est un bon moyen de comparer WebUi et Polymer.

Et enfin pour ceux qui ont déjà fait du WebUI et qui veulent migrer vers Polymer, voici deux ressources :

mercredi 4 septembre 2013

Pub + Barback, le duo gagnant

À boire et à manger !
#dartlang #pub

En juin, Bob Nystrom de l'équipe Dart annoncait Bartender, un fournisseur de ressources embarquées dans des packages Dart tel que des images, des css, … Il n’était qu’au stade de la spécification mais il a eu le temps de changer de nom, désormais Barback, mais aussi d’être implémenter au cours de l’été. Nous n’allons pas revenir sur ses fonctionnalités, tel que la génération de ressource, ou bien la transformation d’une ressource d’un type vers un autre, mais plutôt vous annoncer que cette librairie est embarquée dans pub ! What else ?
Et bien, ce ne serait intéressant de publier des ressources que si on a un serveur sur lesquelles les publier. C’est désormais possible grâce à la commande pub serve !
A la racine de votre projet, lancez la commande pub serve et vous voilà avec votre appli sur localhost:8080. Voici comment s'architecture le serveur :
  localhost/<...>/packages/<pkg>/<path> → <pkg>/lib/<path>
  localhost/<...>/assets/<pkg>/<path> → <pkg>/asset/<path>
  localhost/<anything else> → <your pkg>/web/<anything else>

On retrouve donc le fichier _dart.js_ à cette adresse :
  http://localhost:8080/packages/browser/dart.js
Mais aussi :
  http://localhost:8080/par-là/packages/browser/dart.js

Grâce à ça, on peut pointer vers des ressources directement avec les imports “package:...” et il n’y a plus besoins des liens symboliques vers les répertoires des packages !

La fonctionnalité de transformation n’est pas encore disponible, mais le sera dans les prochaines versions. Peut-être que ce serveur embarqué sera aussi capable de compiler le JavaScript à la volé ?

Sources: