Skip to content

Date archive for: novembre 2011

Tutorial : Premier développement Google AppEngine avec Go

Update: Quelques modifications sont à prendre en compte suite à l’arrivée de la version 1 de Go (vous pouvez utiliser l’application gofix pour mettre à jour votre code et changer la version d’api de 3 à go1).

Le but de cet article est d’expliquer comment mettre en ligne une application AppEngine en Go.

Je ne vais pas m’étendre sur l’installation du SDK et sur la structure du langage :

Et en avant pour cette première application.

Développement d’un générateur de triangle de Sierpinski en Go

Ce programme tout bête utilise un algorithme binaire tout simple pour générer un triangle de Sierpinski dont la taille est paramétrable (paramètre passé en ligne de commande). Pour plus de détails, suivez les commentaires du programme.

package main

import (
  "fmt"
  "strings"
  "strconv"
  "flag"
  "os"
)

func main() {
  // Analyse de la ligne de commande
  flag.Parse()

  // La variable chargée de stocker le nombre de lignes
  // à afficher
  var nbLignes int

  // Parsing des paramètres en ligne de commande
  if flag.NArg() == 0 {
    // Si pas d'arguments => 16 lignes
    nbLignes = 16
  } else {
    // Sinon, on prend la valeur passée en paramètres
    var err os.Error
    nbLignes, err = strconv.Atoi(flag.Arg(0))
    if err != nil {
      fmt.Println(err)
      os.Exit(1)
    }
  }

  // Algorithme d'affichage du triangle
  for i:=0; i<=(nbLignes - 1); i++ {
    // Padding pour redresser le triangle
    fmt.Print(strings.Repeat(" ", nbLignes -i))

    // Construction d'une ligne
    for j:=0;j<=i;j++ {
      if ((^i & j) != 0) {
        fmt.Print("  ")
      } else {
        fmt.Print(" *")
      }
    }
    fmt.Print("\n")
  }
}

Exemple de triangle généré :

                 *
                * *
               *   *
              * * * *
             *       *
            * *     * *
           *   *   *   *
          * * * * * * * *
         *               *
        * *             * *
       *   *           *   *
      * * * *         * * * *
     *       *       *       *
    * *     * *     * *     * *
   *   *   *   *   *   *   *   *
  * * * * * * * * * * * * * * * *

Modification du code pour tourner sur GAE

Nous allons maintenant nous attaquer à la version Google AppEngine.

Tout d’abord, installez le SDK (passez par le site en anglais pour pouvoir télécharger le sdk : http://code.google.com/intl/en/appengine/downloads.html)

Un programme Google AppEngine se base sur le package http de Go pour mettre en place un handler de connexion.
Exemple:

import "http"

func init() {
    http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w, "Hello");
}

En première intention, nous allons faire un programme qui affiche un triangle de Sierpinski de 16 lignes, non paramétrable.
Il faudra alors :

  • Modifier le nom de package (le package main est réservé aux programmes individuels)
  • Ajouter une procédure init()
  • Modifier la méthode main en handler HTTP
  • Supprimer le code de paramétrage du nombre de lignes
  • Supprimer les imports inutilisés

Voici ce que ça donne :

package handler

import (
  "fmt"
  "strings"
  "net/http"
)

func init() {
  http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
  nbLignes := 16

  fmt.Fprint(w, "<html><pre>");

  // Algorithme d'affichage du triangle
  for i:=0; i<=(nbLignes - 1); i++ {
    // Padding pour redresser le triangle
    fmt.Fprint(w, strings.Repeat(" ", nbLignes -i))

    // Construction d'une ligne
    for j:=0;j<=i;j++ {
      if ((^i & j) != 0) {
        fmt.Fprint(w,"  ")
      } else {
        fmt.Fprint(w," *")
      }
    }
    fmt.Fprint(w,"\n")
  }

  fmt.Fprint(w, "</pre></html>");
}

Publication de l’application sur Google AppEngine

Pour publier sur GAE, votre application doit respecter une arborescence du type :

sierpinski/
  app.yaml
  sierpinski/
    sierpinski.go

où app.yaml est le descripteur de l’application :

application: sierpinski-go
version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
  script: _go_app

Les éléments à indiquer dans le fichier sont les suivants :

  • L’identifiant de l’application (que vous déclarez lors de l’enregistrement de l’application dans GAE)
  • La version de l’application (1 pour l’instant)
  • La version d’API de go à utiliser
  • Dans la partie handlers, il faut déclarer l’expression régulière servant à déclarer les pages devant être servies par le script; ici, toutes les pages

Si tout est ok, vous pouvez maintenant tester votre application :

dev_appserver.py sierpinski/

Connectez votre navigateur sur http://localhost:8080 et vous devriez obtenir votre triangle :)

Dernière étape : la publication.

Lancez alors la commande :

appcfg.py update sierpinski/

Après quelques secondes, votre application sera disponible sur GAE.

Le résultat :
[ http://sierpinski-go.appspot.com ]

Bonus : paramétrer le nombre de lignes à afficher

Pour se faire plaisir et pousser un peu plus le concept, ajoutons un paramètrage du nombre de lignes à afficher :

package handler

import (
  "fmt"
  "strings"
  "strconv"
  "net/http"
)

func init() {
  http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
  // Nombre de lignes par défaut
  nbLignes := 16

  // Parsing du nombre de ligne depuis l'url
  nbLignesParam := r.FormValue("nbLignes")
  if nbLignesParam != "" {
    nbConv, err := strconv.Atoi(nbLignesParam)
    if err == nil && nbConv <= 64 {
      nbLignes = nbConv
    }
  }

  fmt.Fprint(w, "<html><pre>");

  for i:=0; i<=(nbLignes - 1); i++ {
    // Padding pour redresser le triangle
    fmt.Fprint(w, strings.Repeat(" ", nbLignes -i))

    // Construction d'une ligne
    for j:=0;j<=i;j++ {
      if ((^i & j) != 0) {
        fmt.Fprint(w,"  ")
      } else {
        fmt.Fprint(w," *")
      }
    }
    fmt.Fprint(w,"\n")
  }

  fmt.Fprint(w, "</pre></html>");
}

(peu de modifications : ajout de l’import strconv et parsing de l’url avec request.FormValue)

On redéploie !

appcfg.py update sierpinski/

Si vous avez déjà déployé la version précédente, il faudra sélectionner la bonne version à publier dans la console appengine

Et voilà le résultat :
[ http://sierpinski-go.appspot.com/?nbLignes=64 ]

ou encore, la version 32 lignes :

                                 *
                                * *
                               *   *
                              * * * *
                             *       *
                            * *     * *
                           *   *   *   *
                          * * * * * * * *
                         *               *
                        * *             * *
                       *   *           *   *
                      * * * *         * * * *
                     *       *       *       *
                    * *     * *     * *     * *
                   *   *   *   *   *   *   *   *
                  * * * * * * * * * * * * * * * *
                 *                               *
                * *                             * *
               *   *                           *   *
              * * * *                         * * * *
             *       *                       *       *
            * *     * *                     * *     * *
           *   *   *   *                   *   *   *   *
          * * * * * * * *                 * * * * * * * *
         *               *               *               *
        * *             * *             * *             * *
       *   *           *   *           *   *           *   *
      * * * *         * * * *         * * * *         * * * *
     *       *       *       *       *       *       *       *
    * *     * *     * *     * *     * *     * *     * *     * *
   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

[ http://sierpinski-go.appspot.com/?nbLignes=32 ]