Actividad 14: Diseño de Algoritmos Paralelos Actividad 14: Diseño de Algoritm...
Un poco más allá con grails. PrimerViernes
1. Un poco más allá con
Grails
Daniel Latorre
dani@primerviernes.com
11/03/2011 – Madrid on Rails
PrimerVienes
2. ¿Quién?
Cofundador de Jobsket.com
Desarrollador independiente
Principalmente Grails/Groovy/Java
Google Summer of Code 2008 y contribuidor Open Source
Web: http://www.danilat.com/
CV: http://www.jobsket.es/cv/dani
Twitter: @dani_latorre
3. ¿Qué es Grails?
Framework web para la plataforma Java “full stack”. Escrito
en Groovy y Java utilizando como base varias herramientas
maduras(Spring, Hibernate, Tomcat...).
CoC & DRY.
Fuertemente inspirado en Ruby on Rails.
4. Principales características
de Groovy
Menos ceremonioso y más expresivo que Java
Todo es un objeto (no hay tipos primitivos)
Compilado o script
Imports por defecto (java.util.*, java.io.*, java.net.*,
java.math.BigDecimal, java.math.BigInteger, groovy.util.*)
Compilación cruzada (Joint compilation)
El GDK extiende a la JDK
Expandos y MOP (añade y modifica atributos y métodos en
tiempo de ejecución)
5. Artefactos de Grails
Clases de Dominio (GORM)
Servicios
Controladores
Vistas + layouts
Librerías de tags
Filtros
Codecs
6. Soporte I18N
Un properties por Locale.
Cambio de idioma con /book/list?lang=en.
<g:message code="my.localized.content" args="${['Juan']}"/>
message(code:"my.localized.content", args:['Juan'])
Podemos inyectar messageSoruce de Spring en cualquier
parte.
Usando Spring podemos incluso modificar el origen de datos
del messageSoruce.
7. Externalizar configuraciones
Base de datos por JDNI. En el DataSoruce.groovy:
dataSource {
jndiName = "java:comp/env/myDS"
}
Configuración del Config.groovy:
grails.config.locations = [ "classpath:${appName}-config.groovy","file:$
{userHome}/.grails/${appName}-config.groovy"]
10. Envío de emails
Mail Plugin, para envíos por SMTP
Postmark Plugin, servicio que asegura la recepción.
Existen varios plugins con más funcionalidades
11. Lazy/eager loading
Por defecto los objetos relacionados se cargan de forma
perezosa.
Podemos necesitar una session diferente al
OpenSessionInView de Grails/Spring
static mapping = {
books lazy: false
}
NO evitamos el problema de N + 1 queries.
12. Evitando el problema N+1
La solución: fetch.
A nivel de relaciones GORM:
static mapping = {
books fetch: 'join'
}
En las consultas:
Author.findAllByNameLike("John%", [fetch: [location: 'join'] ])
13. Caché de primer nivel de Hibernate
Caché de primer nivel para ahorrar tráfico en red y
aumentar la velocidad.
Sin flush:true en save o delete, no se persisten los
cambios hasta que hibernate ejecute el próximo select.
14. Caché de segundo nivel de
Hibernate
Se cachea cada insancia de la clase de Dominio:
static mapping = {
cache 'read-only' // cache true
}
read-only: Si los datos son sólo lectura.
non-strict-read-write: Para pocas actualizaciones, no asegura si varias
transacciones modifican la misma instancia.
read-write: Actualizaciones frecuentes. Al modificar se actualiza en
cache, no soporta transacciones y pueden surgir inconsistencias.
transactional: Necesita un proveedor que lo soporte(JBoss TreeCache)
15. Caché de consultas de Hibernate
Es posible cachear queries indicándolo al ejecutar.
Habitual para consultas que se repitan de forma
constante
def person = Person.findByFirstName("Fred", [cache:true])
16. ¿Opciones para una política de
caché propia?
EhCahe
OSCahe
Memcache
JBoss Cache
Terracota
¿Bases de datos NoSQL?: Redis, Mongo...
17. Caché de métodos de un Service
con SpringCache
Puede interesar cachear las llamadas al método de
algún Service.
@Cacheable("pirateCache")
def getPirates() {...}
@CacheFlush("pirateCache")
void registerNewPirate(Pirate pirate) {...}
18. Caché de HTML con SpringCache
Cachear porciones de HTML es una práctica habitual.
Para hacerlo se combina SpringCache y el tag include en
las vistas.
@Cacheable("albumControllerCache")
def list = {...}
@CacheFlush("albumControllerCache")
def save = {...}
19. Caché HTTP
Podemos cachear a nivel de navegador jugando con las
cabeceras HTTP. Ahorrando tráfico y CPU.
Con el plugin Caching Headers, antes de los renders de los
actions a cachear:
cache shared:true, validFor: 3600 // 1hr on content
cache shared: true, validUntil: new Date()+1
lastModified book.dateUpdate
Hay disponible también un DSL con withCacheHeaders, para permitir
más flexibilidad.
20. Caché de estáticos
Resources plugin: comprime .js/.css
Cache-resources plugin: añade manejo de cacheo de
estáticos al navegador.
21. Sistemas de mensajería
Hay que tratar quitar lo máximo de la request para
mejorar la velocidad, la UX y facilitar la escalabilidad.
JMS Plugin. Java Message Service
Rabbit MQ Plugin. Advanced Message Queuing Protocol
Jabber Plugin.
Solución Do It Yourself(Con quartz o java.util.concurrent)
22. Optimizando para móviles
Es posible detectar si el navegador es un teléfono en el
request.getHeader('user-agent'). Para ahorrar ese trabajo
manual, SpringMobile.
def list = {
withMobileDevice {def device ->
if(device.id.contains("iphone"){
render(view: "iphoneList", model: [list: listInstance])
}
render(view: "mobileList", model: [list: listInstance])
}
render(view: "list", model: [list: listInstance])
}
23. Optimizando para móviles II
En la parte de front, hay que optimizar también el html,
tamaño de ficheros estáticos, imágenes, etc.
Para smartphones, HTML5: Soporte de geolocalización,
Web Database...
Librerías Javascript que pueden ayudar: Sencha Touch
o jQuery Mobile.
24. Algunos enlaces de interés
Postmark, servicio de mailing: http://postmarkapp.com/
Reading i18n messages from the database with Grails: http://1vm.es/000K
SpringSecurity with SpringCache: Caching content per user: http://1vm.es/000L
Localizable plugin: https://github.com/danilat/localizable