PrettyTime
• Représenter des dates «relatives»
– par rapport à «maintenant»
• On souhaite savoir...
– il y a combien de temps que...
– dans combien de temps...
• Plutôt que de connaître la date absolue et précise
– du coup, meilleure notion de la fraîcheur dʼune information
– surtout valable pour des laps de temps courts
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
PrettyTime
• Librairie Open Source : LGPL v3
• Version 1.0.7, disponible dans Maven Central
• Léger : 58 ko
• Développé par Lincoln III Baxter / OCPSoft
– Senior Software Engineer chez JBoss / RedHat
• Customisable
– y-compris les langues supportées :
• français, anglais, espagnol, allemand, italien, hollandais,
portugais, bulgare, chinois, croate, estonien, hongrois, norvégien,
polonais, roumain, slovénien, turque, vietnamien
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 11
Dépendance
• Si vous nʼavez pas de chance...
<dependency>
<groupId>com.ocpsoft</groupId>
<artifactId>ocpsoft-pretty-time</artifactId>
<version>1.0.7</version>
</dependency>
• Si vous avez de la chance...
– dans un script Groovy
@Grab('com.ocpsoft:ocpsoft-pretty-time:1.0.7')
import com.ocpsoft.pretty.time.PrettyTime
– ou avec Gradle
dependencies {
compile 'com.ocpsoft:ocpsoft-pretty-time:1.0.7'
}
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 12
Vie de cochon... cʼest bien ma veine...
C’est bien
mais ch’préfère utiliser
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 13
Allez, des morceaux de code !
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
Comment lʼutiliser ?
@Grab("com.ocpsoft:ocpsoft‐pretty‐time:1.0.7")
import com.ocpsoft.pretty.time.PrettyTime
long seconds = 1000
long minutes = 60 * seconds
long hours = 60 * minutes
long days = 24 * hours
long weeks = 7 * days
long months = 31 * days
long years = 365 * days
long now = new Date().time
def p = new PrettyTime()
[
[ 0, "à l'instant" ],
[ 10 * minutes, "dans 10 minutes" ],
[ ‐3 * hours, "il y a 3 heures" ],
[ 9 * days, "dans 1 semaine" ],
[ ‐2 * weeks, "il y a 2 semaines" ],
[ 3 * months, "dans 3 mois" ],
[‐15 * years, "il y a 1 décénie" ],
[111 * years, "dans 1 siècle" ]
].each { diff, text ‐>
assert p.format(new Date(now + diff)) == text
}
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
Comment lʼutiliser ?
@Grab("com.ocpsoft:ocpsoft‐pretty‐time:1.0.7")
import com.ocpsoft.pretty.time.PrettyTime
long seconds = 1000
long minutes = 60 * seconds
long hours = 60 * minutes
long days = 24 * hours
long weeks = 7 * days
long months = 31 * days
long years = 365 * days
long now = new Date().time
def p = new PrettyTime()
[
[ 0, "à l'instant" ],
[ 10 * minutes, "dans 10 minutes" ],
[ ‐3 * hours, "il y a 3 heures" ],
[ 9 * days, "dans 1 semaine" ],
[ ‐2 * weeks, "il y a 2 semaines" ],
[ 3 * months, "dans 3 mois" ],
[‐15 * years, "il y a 1 décénie" ],
[111 * years, "dans 1 siècle" ]
].each { diff, text ‐>
assert p.format(new Date(now + diff)) == text
}
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
Intégration
• PrettyTime sʼutilise facilement nʼimporte où...
– utilisez simplement lʼAPI directement
• Mais PrettyTime propose une intégration JSF
<h:outputText value="#{exampleBean.futureDate}">
<f:converter converterId="com.ocpsoft.PrettyTimeConverter"/>
</h:outputText>
• Il existe également un plugin Grails
<prettytime:display date="${someDate}" />
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 17
Loi de Moore
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 21
Le constat...
• Les architectures de nos ordinateurs évoluent
– simple vers multi-processeurs (cʼest pas nouveau)
– simple vers multi-coeurs
• On atteints les limites de la loi de Moore
• Nos applications devront évoluer pour sʼadapter
– pour tirer parti des multiples coeurs et processeurs
• Groovy se devait de proposer des solutions pour la
programmation concurrente et parallèle
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 22
Lʼâge de pierre
• Il est difficile de bien utiliser
– les threads
– synchronize
– wait / notify / notifyAll
• On obtient rapidement
– des dead-locks et live-locks
– des race conditions
– des starvation
• Problème de gestion dʼaccès à de la mémoire partagée
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
GPars
• GPars est Open Source : Apache Software Licence 2
• Version actuelle : 0.12
• Dépendances
– jsr166y et extra166y (1.7.0)
– groovy, si vous lʼutilisez
• GPars est bundlé avec la distribution de Groovy
– mais peut-être téléchargé individuellement
• Et surtout, GPars a une API Java !
– pas seulement pour Groovy
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 27
Un large panel de solutions
• actors
• fork / join
• map / filter / reduce avec parallel arrays
• executors (java.util.concurrent)
• dataflow (operators et streams)
• agents
• STM (Software Transactional Memory)
• CSP (Communicating Sequential Processes)
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 28
Fonctions parallèles pour les collections
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 31
Map / filter / reduce
• Concept popularisé par le papier de Google
– approche utilisée initialement pour la création
de lʼindex du moteur de recherche
import static groovyx.gpars.GParsPool.withPool
withPool(5) {
def nums = 1..100000
println nums.parallel.
map { it ** 2 }.
filter { it % 7 == it % 5 }.
filter { it % 3 == 0 }.
reduce { a, b -> a + b } // sum()
}
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
Map / filter / reduce
• Opérations sur les «parallel arrays» (JSR-266)
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
Fork / join
• Principe du « diviser pour mieux régner »
– découper un problème en plus petits morceaux
• Problématiques récursives
– merge sort, quick sort
– traverse de graphe
– recherche sur un système de fichiers
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 34
Dataflow
• Approche moins connue mais avec nombreux avantages
– pas de « race conditions »
– pas de « live locks »
– des « deadlocks » déterministes
• Tâches, utilisant des variables assignables une seule fois
– possibilité dʼutiliser des «flux» pour des données en continu
• Le dataflow gère le graphe des tâches à résoudre
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 39
Dataflow
import groovyx.gpars.dataflow.DataFlows
import static groovyx.gpars.dataflow.DataFlow.task
new DataFlows().with {
task { a = 10 }
task { b = 5 }
task { x = a - b }
task { y = a + b }
task { result = x * y }
assert 50 == result
}
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 40
Agents
• En anglais dans le texte (documentation de GPars)
– a thread-safe non-blocking shared mutable state wrappers
– thread-safe : utilisable par des threads concurrents
– non-blocking : pas de «synchronized» et dʼattente pour accéder
à la resource
– shared mutable state : donnée partagée qui peut changer de
valeur (non immuable)
– wrapper : lʼagent est un wrapper autour de la donnée à
manipuler
• Concept inspiré par les « agents » de Clojure
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 41
Thank you!
e
L aforg pment
aume vy Develo
Guill Groo m
Hea d of g mail.co
aforge@
mail: gl glaforge e
E @ o /glaforg
T witter : http://gplus.t
Go ogle+:
@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 46