Fedora-Fr - Communauté francophone Fedora - Linux

Planet de Fedora-Fr : la communauté francophone autour de la distribution Linux Fedora

A propos

Cette page est actualisée toutes les heures.

Cette page est une sélection de blogs autour de Fedora. Fedora-Fr.org décline toute responsabilité au sujet des propos tenus par les auteurs des blogs de ce planet. Leurs propos sont leur entière responsabilité.

Le contenu de ce planet appartient à leurs auteurs respectifs. Merci de consulter leur blogs pour obtenir les licences respectives.

Mot-clefs : google

Go, routines et canaux - introduction au langage

Patrice Ferlet

Il y tellement de nouveaux langages, quand un de ceux là sort du lot c'est en général parce qu'il offre des concepts particuliers. Go est un de ceux là, et les concepts de routines, de canaux et de fonctions différées ne sont qu'une infime partie des possibilités que vous pouvez découvrir dans ce langage. Testons un peu ce langage.

Jai la chance daimer mon métier, et dans ce métier on apprend souvent de nouvelles choses, des concepts, des langages... Dans le panel de langages informatique que jai put entrevoir, certains mont vraiment surpris dans leur concept. Le premier dont jai eut beaucoup de mal à mapprocher est le Haskell, et depuis peu je me penche sur Go. Je mempresse donc de vous montrer un peu lintérêt que je vois dans ce langage.

Cest Nicolas Engel, avec qui jai travaillé sur un projet, qui men a reparlé et lenvie de me repencher sur Go sest vite manifesté.

Alors Go cest quoi ?

Ce langage a été créé par une équipe de Google depuis 2010 et a pour vocation de réduire des problématiques que beaucoup de développeurs doivent supporter dans dautres langages. Vous pouvez utiliser le compilateur Go à télécharger ici: http://golang.org/ ou utiliser gcc-go (package Fedora disponible dans les dépots officiels)

Cest un langage compilé, performant et sous licence BSD... La seule complication, et vous allez voir quelle est dominante au début, cest que le concept est vraiment différent de pas mal de langages. Amis développeurs Python, Java, PHP et même C/C++... vous allez être un peu surpris.

La raison principale de la création de ce langage a été motivée par la réduction de problématiques telles que les threads, les sémaphores, les transferts interprocessus, les fractures mémoire, et limpérativité des langages communs. Vous allez voir que des concepts ont été ajoutés à Go pour rendre tout cela vraiment très simple... si si, cest finalement très simple.

Tout dabord, cest un langage fortement typé, les habitués de langages typés dynamiquement vont devoir se faire une raison: il va falloir déclarer vos variables. Ensuite, Go nest pas un langage purement objet mais vous allez facilement pouvoir déclarer des struct avec des méthodes attachées. Jentends dici pas mal dentre vous rire doucement sur un fond de “huhu aujourdhui faire un langage non objet... cest juste revenir dans le passé, autant faire du C”. Je tiens à donner mon avis là dessus, les langages orientés objet ont leurs avantages certains, mais Go est surtout fait pour être performant dans un premier lieu, et le C na rien de vieillot car même votre Linux, votre Mac ou votre Windows est un système dexploitation quasiment entièrement écrit en C.

Enfin, pour ma part, je nai aucun mal à imaginer développer une grosse infrastructure logiciel avec un langage structuré non objet. Et surtout si cest en Go. Dans tous les cas, Go est adressé aux développeurs désirant un langage proche du processeur, un peu comme C/C++ tout en gardant des simplification en terme de threads, sémaphores et gestion mémoire. Bien que Go permette de créer aussi des application web, et se retrouve même dans Google AppEngine. Voyez le guide de démarrage: go appengine.

Bref, passons la polémique trollesque et passons au langage lui même.

On commence par installer le compilateur. Soit vous utilisez gcc-go (dans les dépots) soit vous utilisez le compilateur de google à cette adresse: Golang. Je vous conseille, pour commencer, d'utiliser celui de google et de suivre la manière dont on utilise le runtime. En général, cela revient à faire la commande

go run monfichier.go

Pour le compiler réellement:

go build monfichier.go

Je ne vais pas vous détailler les bases du langage, mais un exemple rapide pour vous donner la syntaxe de base:

package main
 
//fmt est le package de formatage de chaine
import “fmt”
 
//on retrouve une fonction main
func main () {
     fmt.Println(“Hello le mondo !);
}

Bon rien de bien compliqué, un hello world bateau. Vous remarquez donc quon a une notion de package, et donc quon pourra séparer des fonctions et structures dans différent package (ce qui est un plus quand on se réfère au C). Cela ressemble fortement aux espace de nom (namespace) mais lidée est plus claire selon moi.

Petite parenthèse, vous allez rapidement vous rendre compte au fur et à mesure que la plupart des concepts en Go se retrouve dune manière ou dune autre dans C.

Alors ya quoi de nouveau ?

Dabord, comment on déclare une variable ? et bien de deux façons:

// i variable de type int
var i int
i = 4
 
//ou bien
//i est une entier valant 4, le typage est déduit par inférence
i:=4

Pour faire simple, utiliser ":=" (oubliez pas les deux points) pour déclarer en assignant, sinon l'assignation se fait avec un simple "="

Voilà, pas plus pas moins... on va pas parler de pointeur et de structure de suite, mais vous naurez pas de mal à comprendre en lisant la documentation ou en faisant le gotour (voir les liens en fin de billtet)

Je vais vous lister 3 concepts qui mont plut dans ce langage. Le premier est le concept de “goroutine” qui est foncièrement parlant une méthode pour créer des threads sans se prendre la tignasse et se taper le front sur le clavier. Le second concept est le principe de canal (channel) qui permet tellement de choses quon sattriste de ne pas les avoir dans les autres langages (du moins pas sous cette forme). Un canal permet de faire transiter des valeurs dun processus à lautre, de bloquer un processus tant quun autre nest pas terminé et en plus de bufferiser tout ça. Cest le concept de sémaphore (mutex) amélioré dans sa conception. Le troisième concept est la possibilité de différer un appel dans le temps (defer). Cela rend le code lisible à souhait.

Un autre concept, que lon retrouve un peu en python, est le fait de pouvoir retourner plusieurs valeurs de plusieurs types depuis une fonction. Ceux qui nont pas compris lintérêt devrait penser simplement à cela: imaginez une fonction qui retourne un résultat et un code derreur. Plutôt que de devoir retourner une structure, ou un objet pour les langages qui le permettent, on retourne une liste simple de variables.

Bref, passons aux goroutines de suite.

Lappel à une routine se fait simplement via le mot clef “go”. La fonction sera appelée dans un thread (mais dans le même processus, on ne parle pas dun fork ici, mais bien dun thread) et rien dautre nest à faire !

Je ne vous ai pas encore parlé des canaux, donc cet exemple ne va pas fonctionner exactement comme on le veut, mais le concept est là. Ne cherchez pas si ça fonctionne mal chez vous.

package main
 
import "fmt"
 
func hello(you string){
    for i:=0; i<5; i++ {
        fmt.Println("hello you:" + you)
    }
}
 
func main (){
    go hello("Pierre")
    hello ("Paul")
}

Ce qui va vous donner (selon la manière dont les threads sont créé sur votre OS):

hello you:Paul
hello you:Pierre
hello you:Paul
hello you:Pierre
hello you:Paul
hello you:Pierre
hello you:Pierre
hello you:Pierre
hello you:Paul
hello you:Paul

Vous lavez remarqué, jai parfois 3 fois “Pierre” qui apparait, parfois 2 fois “Paul”. Cela est le fait que la routine est géré selon les disponibilités du CPU.

Bon, on passe aux canaux. Là vous risquez de perdre un peu le fil, mais je vous assure que la capacité de ce concept est tout bonnement génial.

Un canal est un type dont le principe est dempiler des valeurs et de bloquer le processus si on cherche à lire dedans, et que celui-ci si il est vide. Cest le principe du FIFO. Lintérêt est sa syntaxe aisée et lisible.

Il faut utiliser la fonction “make” (genre de malloc, mais orienté fabrique ou factory) pour créer un “chan”.

//canal prenant des entiers
c := make (chan int)

Un canal peut prendre n'importe quel type, entier, flottants, chaines... et même des structures.

Ensuite cest plutôt simple... On utilise “<-” pour placer des valeurs dans le flux.

Donc:

//empile un entier (1) dans le canal
c <- 1

Et pour lire le canal

//bloque tant que rien nest empilé dans c
//on peut récupérer la valeur empilée
int val := <-c2
//ou simplement attendre une écriture dans la canal
<-c2

Faisons simple, on va juste comprendre le principe du canal:

package main
 
import "fmt"
 
func routine(a, b chan int){
     i := <-a
     fmt.Printf("je viens de lire dans le canal: %d\n", i);
 
     //'main' attend toujours, je vais écrire dans le canal b
     //pour le débloquer
     b <- 0
}
 
func main(){
    a,b := make(chan int), make(chan int)
 
    //on écrit dans a
    a <- 2
    //on lance une fonction en parallèle
    //qui reçoit les deux canaux en paramètres
    go routine1(a,b)
 
    //on va attendre la fin de la routine
    //la routine doit écrire dans le canal b 
    //pour que cette instruction se débloque
    <- b
    fmt.Println("voilà, j'ai fini, b a été lut")
}

Pour le moment on s'amuse à débloquer des canaux en écrivant dedans. Sachez que vous pouvez fermer un canal avec la fonction "close" mais si vous en avez besoin, c'est que vous être dans un cas particulier. Car en fait, Go n'aime pas que des canaux restent ouverts avec une valeur bloquée et non lut... pensez à traiter correctement les canaux, sinon forcez la fermeture avec "close"

Voyons un autre exemple de code qui va fonctionner avec un canal dentier. Un peu plus salé par contre...

package main
 
import "fmt"
import "time"
 
 
func thread1 ( sem, done chan int) {
    fmt.Println("je suis le thread 1, je commence à bosser")
 
    //grosse fonction qui prend du temps
    time.Sleep(1 * 1e9)
 
    //on débloque le sémaphore
    sem<-0
    //on travaille encore un peu
    time.Sleep(1 * 1e9)
    fmt.Println("je suis le thread 1, je préviens main que je termine")
    //je préviens que la routine est finie
    done<-1
}
 
//voir plus bas (dans thread2), 
//cette méthode va permettre
//une exécution différée
func send(c chan int, num int) {
    c <- num
}
 
func thread2 (sem, done chan int) {
    //autre manière de s'assurer qu'on écrit bien à la
    //fin de la fonction :
    //defer permet de différer l'appel à "send" 
    //à la fin de ma fonction
    defer send(done, 2) 
 
    fmt.Println("je suis le thread 2, je commence à bosser")
 
    //on attend la fin de thread 1
    <-sem
    fmt.Println("je suis le thread 2, on m'a débloqué")
 
    //on bosse encore un peu
    time.Sleep(2 * 1e9)
 
    //quant sleep a terminé, la fonction différée va
    //être exécutée
}
 
func main(){
    //sem va me permettre de gérer les bloquage et débloquage
    //des goroutines
    sem := make (chan int)
 
    //ce canal sera emplilé par la seconde routine pour dire
    //à la fonction main qu'il a terminé
    done := make (chan int)
 
    //on lance les deux routine en parallèle, elle vont communiquer
    //au traver de sem
    //on remplira "done" pour dire que le thread est terminé
    go thread1 (sem, done)
    go thread2 (sem, done)
 
    fmt.Println("je suis dans main, j'attend la fin en lisant le canal 'done'")
 
    //les routines vont écrire dans "done",
    //j'attend que ce soit le cas pour les deux threads
    //donc on attend 2 fois
    //la variable i récupérera la valeur envoyé dans le canal
    var i int
    i = <-done
    fmt.Printf("routine %d vient d'écrire dans le canal 'done'\n", i)
    i = <-done
    fmt.Printf("routine %d vient d'écrire dans le canal 'done'\n", i)
 
    fmt.Println("je suis dans la fonction main, on m'a débloqué")
 
}

Voilà ce que donne mon programme:

je suis dans main, j'attend la fin en lisant le canal 'done'
je suis le thread 1, je commence à bosser
je suis le thread 2, je commence à bosser
je suis le thread 2, on m'a débloqué
je suis le thread 1, je préviens main que je termine
routine 1 vient d'écrire dans le canal 'done'
routine 2 vient d'écrire dans le canal 'done'
je suis dans la fonction main, on m'a débloqué

Ce qui est exactement ce que je voulais. La fonction main sest mise en attente, les deux threads on commencé à travailler en parralèle. La routine 1 déblique la routine 2, mais cette routine 1 fini certaines choses en même temps. Enfin, la fonction “main” remprend la main (non cest pas un jeu de mot)...

Plutôt que de créer une fonction "send" qui n'est utilisée que dans le thread 2, on peut utiliser un système de closure. Car en effet, les fonctions en Go sont des closures. Revoyons le code du thread 2:

func thread2 (sem, done chan int) {
    //autre manière de s'assurer qu'on écrit bien à la
    //fin de la fonction :
    //on crée une closure exécutée en fin de fonction
    //notez que c est local à la closure, la closure prend "done"
    //en argument, donc c correspondra à done
    defer func (c chan int) {
        c <- 2 
   }(done)
 
    fmt.Println("je suis le thread 2, je commence à bosser")
 
    //on attend la fin de thread 1
    <-sem
    fmt.Println("je suis le thread 2, on m'a débloqué")
 
    //on bosse encore un peu
    time.Sleep(2 * 1e9)
 
    //quant sleep a terminé, la fonction différée va
    //être exécutée
}

Vous pouvez donc supprimer la fonction "send". On retrouve ici un concept de fonction "inline" interne à une fonction. En bref, la capacité qu'à Go à vous simplifier la vie est vraiment intéressante.

Bref, là je nai fait quune introduction à Go... je nai pas le recul ni lexpérience nécessaire pour aller plus dans le détail (bien que je mamuse comme un fou avec des tests bourrins). Je vous conseille daller lire le “gotour” ici : GoTour. Je vous conseille de bien vous pencher sur les notions de "range", de retour de plusieurs variables depuis une fonction mais aussi sur les concepts de structure et fonctions de structure. Ce billet ne visait qu'à vous éclairer sur ce que peut vous apporter Go coté parallélisation.

Go est désormais utilisable dans appengine, vous pouvez aussi créer votre propre miniserveur HTTP très facilement avec le package (inclu) "net/http" et que des portage de Gtk, WX etc... ont vu le jour et fonctionnenent.

En ce qui concerne les deux compilateurs, le compilateur (et runtime) Go de Google compile de manière statique mais donne de superbe résultats en terme de performances. Vous pouvez utiliser gcc-go (dans les dépots Fedora du moins) qui vous permettra de compiler dynamiquement vos programmes (le compilateur go faisant de la compilation statique...)

Un dernier point, Go vous permet aussi de récupérer très aisément des librairies C et dutiliser les fonctions impémentées dans ce langage.

Google App Engine et le souci os_compat

Patrice Ferlet

Google AppEngine propose est un service de développement web assez puissant et très intéressant qui permet de faire une application "scalable" en Java, Python et maintenant en Go. Le souci, si comme moi vous avez "MyPaint" et par conséquent le paquet protobuf-python... vous allez vous taper une erreur monstrueuse au démarrage de votre application... on va trouver une méthode simple pour contourner ce souci

Car effectivement, au premier lancement de votre application:

 ./google_appengine/dev_appserver.py helloworld/
Traceback (most recent call last):
  File "./google_appengine/dev_appserver.py", line 125, in <module>
    run_file(__file__, globals())
  File "./google_appengine/dev_appserver.py", line 121, in run_file
    execfile(script_path, globals_)
  File "/home/patachou/Dev/google_appengine/google/appengine/tools/dev_appserver_main.py", line 138, in <module>
    from google.appengine.tools import os_compat
ImportError: No module named appengine.tools

Pourquoi ? tout simplement parce que le paquet protobuf contient un module nommé... google ! du coup, python ne va pas voir ailleurs que dans le site-package protobuf et plante misérablement, lachant son dernier souffle en vous insultant... et vous, vous n'avez que pour seule solution de vous rabattre tant bien que mal sur des discussions sur le net où tout le monde vous demande de supprimer protobuf.

Sauf que moi, j'utilise MyPaint et j'ai pas envie de me remettre le paquet à chaque fois que je veux dessiner. Et puis de toutes manières j'aime pas les méthodes où il faut supprimer un paquet tout simplement parce qu'une implémentation sent la fosse septique...

La solution ? oui oui deux secondes...

Elle est simple ma solution... utiliser un environnement virtuel ! Attention, pas un LXC ou une VM qui va vous plomber tout votre espace disque... non ! juste un outil python qui rend tellement service, et dont je me sers tout le temps pour tester mes "setup.py" et autres joyeusetés qui peut simplement foutre le boxon dans mes répertoires.

Bref, on va faire ça propre !

On crée un environnement virtuel

mkdir -p ~/Dev/appengine
virtualenv ~/Dev/appengine

Voilà, c'est fait... on copie maintenant le répertoire "google" fournis avec le SDK Python de Google App Engine:

cp -ra ~chemin/vers/google_appengine/google ~/Dev/appengine/lib/python2.7/site-packages/

Et pour lancer l'engin google, on active l'environnement:

source ~/Dev/appengine/bin/activate

Du coup, on voit notre prompt terminal commencer par: (appengine), chez moi ça donne:

(appengine)[patachou@patrice-laptop ~]$

Vous pouvez maintenant lancer votre programme (prenez le tutorial python 2.7 de google) de cette manières:

~chemin/vers/google_appengine/dev_appserver.py helloworld/

Pour sortir de l'environnement virutel:

deactivate

Voilà, c'est simple, assez propre, et en plus ça marche...

Point de montage Google Drive

Patrice Ferlet

Google vient de sortir Google Drive, comprenez un espace de stockage dans le "cloud" (à distance, sur les serveur Google, avec mix des documents de google-docs). L'application de disque dur distant est accessible de plusieurs manières: Android, PC ou directement sur le net. Or sous Windows et Mac on a la possibilité d'utiliser un programme qui monte un disque sur l'ordinateur. Qui dit "monter" rappelle le point de montage Linux (unix...). Google a annoncé une version de Google Drive Linux pour bientôt mais en attendant vous pouvez encore utiliser le projet http://code.google.com/p/google-docs-fs/

Ce projet était à la base un système de montage simple utilisant fuse pour afficher les google-docs sur un disque monté localement. Mais comme Drive utilise le même point d'accès, ce (vieux) projet fonctionne très bien. Sous Fedora, il suffit de faire:


su -c "yum install fuse-python -y"


cd /tmp
hg clone https://code.google.com/p/google-docs-fs/
cd google-docs-fs
su -c "python setup.py install"

Reste alors à monter le dossier:

mkdir ~/GoogleDrive
gmount ~/GoogleDrive votre_user@gmail.com

On vous demande alors le mot de passe google, et hop le point de montage est créé:

mount
gmount.py on /home/patachou/GoogleDrive type fuse.gmount.py (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

Vous pouvez dés lors visiter le dossier, créer des répertoires, copier des données, ouvrir vos documents... et y accéder depuis votre mobile, le net... Reste à voir ce que l'application Google offrira de mieux que ce petit projet python, parce que pour le moment cela me convient tellement bien...

PS: vous pouvez ajouter ce point de montage dans /etc/fstab pour l'avoir actif tout le temps, mais comme je ne sais pas comment placer le mot de passe. Je vous tiens au courant si je trouve :)" class="smiley

Sortie de Compta Partagée

Tom Dubin Mon application Android, Compta Partagée est enfin disponible ! Cette application est née dans mon esprit il y a quelques mois d’un constat simple : Gérer des dépenses à plusieurs est souvent compliqué. La plupart des gens dans ce cas (moi y compris) utilisent un un tableur et quelques macros pour pouvoir avoir un historique [...]

BeMyApp Android d’Avril 2011 : C’est fini !

Tom Dubin Et voilà, le fameux WE BeMyApp dont je vous avais parlé précédemment est terminé. Pour resituer rapidement le contexte, je suis partis avec 3 amis de l’Ensicaen à Paris afin de passer 48H à développer une application pour Android.Nous nous étions débrouillés pour arriver tôt le vendredi soir et cela nous a permis de prendre [...]

Coup de coeur : Calendrier intégré à gnome-shell

Tom Dubin Depuis quelques temps, je test Fedora 15 alpha et donc Gnome-Shell qui va avec… Et, même si le passage par rapport à Gnome 2 est assez perturbant, je m’étonne tout les jours de la rapidité et de la fluidité du bureau. Qui plus est, je commence à prendre en main les fonctionnalités et il est [...]