SlideShare a Scribd company logo
Async and event-driven
Grails applications
Álvaro Sánchez-Mariscal
@alvaro_sanchez
About me
— Coming from Madrid
!
— Developer since 2001 (Java / Spring stack).
— Grails fanboy since v0.4.
— Working @ OCI since 2015: Groovy, Grails & Micronaut!
— Father since 2017!
"
@alvaro_sanchez
Introduction
@alvaro_sanchez
Grails Async Framework
— https://async.grails.org
— Introduced in Grails 2.3 with the Promise API. Spun-
off in Grails 3.3
— Supports different async libraries: GPars, RxJava and
Reactor.
— Application events, Spring events, GORM events.
— Async GORM.
@alvaro_sanchez
Grails Async Framework
— Server Sent Events.
— RxGORM.
— Async request/response processing.
— Servlet 3.0 async support.
@alvaro_sanchez
 Ge"ing started
— Add the dependency in build.gradle:
runtime "org.grails.plugins:async"
— Check the Grails plugin page for more information:
http://plugins.grails.org/plugin/grails/async
@alvaro_sanchez
Servlet 3.0 API
@alvaro_sanchez
 Servlet 3.0
— Spec'ed in 2009!
!
— Allows offloading of blocking operations to a different
thread.
— Implement grails.async.web.AsyncController to get
started.
— Call startAsync() to get the javax.servlet.AsyncContext
— When done, call complete() or dispatch()
@alvaro_sanchez
Demo
@alvaro_sanchez
 Advanced usage
ctx.addListener(new AsyncListener() {
void onStartAsync(AsyncEvent event) throws IOException { }
void onComplete(AsyncEvent event) throws IOException { }
void onTimeout(AsyncEvent event) throws IOException { }
void onError(AsyncEvent event) throws IOException { }
})
ctx.timeout = 5_000
@alvaro_sanchez
Promise API
@alvaro_sanchez
Grails Promise API
— Builds on top of java.util.concurrent.Future.
— grails.async.Promises helps you to create Promise<T>
instances.
— In controllers, better use grails.async.web.WebPromises
(Servlet 3.0 Async under the covers)
— PromiseFactory allows pluggable implementations.
@alvaro_sanchez
PromiseFactory API
— CachedThreadPoolPromiseFactory (default): unbound
thread pool.
— GparsPromiseFactory: if org:grails:grails-async-gpars
dependecy is on the classpath.
— RxPromiseFactory: if either org.grails:grails-async-
rxjava or org.grails:grails-async-rxjava2 are on the
classpath.
@alvaro_sanchez
PromiseFactory API
— SynchronousPromiseFactory: useful for unit testing.
import org.grails.async.factory.*
import grails.async.*
Promises.promiseFactory = new SynchronousPromiseFactory()
@alvaro_sanchez
Demo
@alvaro_sanchez
PromiseList
import grails.async.*
PromiseList<Integer> list = new PromiseList<>()
list << { 2 * 2 }
list << { 4 * 4 }
list << { 8 * 8 }
list.onComplete { List<Integer> results ->
assert [4,16,64] == results
}
@alvaro_sanchez
 PromiseMap
import static grails.async.Promises.*
PromiseMap promiseMap = tasks one: { 2 * 2 },
two: { 4 * 4},
three:{ 8 * 8 }
assert [one:4,two:16,three:64] == promiseMap.get()
@alvaro_sanchez
@DelegateAsync
import grails.async.*
class BookService {
List<Book> findBooks(String title) { ... }
}
class AsyncBookService {
@DelegateAsync BookService bookService
}
@alvaro_sanchez
@DelegateAsync
import grails.async.*
class BookService {
List<Book> findBooks(String title) { ... }
}
class AsyncBookService { //Equivalent
Promise<List<Book>> findBooks(String title) {
task {
bookService.findBooks(title)
}
}
}
@alvaro_sanchez
Using the service
@Autowired AsyncBookService asyncBookService
def findBooks(String title) {
asyncBookService.findBooks(title)
.onComplete { List<Book> results ->
render "Books = ${results}"
}
}
@alvaro_sanchez
Events
@alvaro_sanchez
Grails Events abstraction
— Add the dependency in build.gradle:
runtime "org.grails.plugins:events"
— By default Grails creates an EventBus based off of the
currently active PromiseFactory.
— Or you can use:
— org.grails:grails-events-gpars
— org.grails:grails-events-rxjava
— org.grails:grails-events-rxjava2
@alvaro_sanchez
Publishing events
— With the @Publisher annotation:
class SumService {
@Publisher
int sum(int a, int b) {
a + b
}
}
@alvaro_sanchez
Publishing events
— With the EventPublisher API:
class SumService implements EventPublisher {
int sum(int a, int b) {
int result = a + b
notify("sum", result)
return result
}
}
@alvaro_sanchez
Subscribing to events
— With the @Subscriber annotation:
class TotalService {
AtomicInteger total = new AtomicInteger(0)
@Subscriber
void onSum(int num) {
total.addAndGet(num)
}
}
@alvaro_sanchez
Subscribing to events
— With the EventBusAware API:
class TotalService implements EventBusAware {
AtomicInteger total = new AtomicInteger(0)
@PostConstruct
void init() {
eventBus.subscribe("sum") { int num ->
total.addAndGet(num)
}
}
}
@alvaro_sanchez
GORM events
— DatastoreInitializedEvent
— PostDeleteEvent
— PostInsertEvent
— PostLoadEvent
— PostUpdateEvent
@alvaro_sanchez
GORM events
— PreDeleteEvent
— PreInsertEvent
— PreLoadEvent
— PreUpdateEvent
— SaveOrUpdateEvent
— ValidationEvent
@alvaro_sanchez
Asynchronous subscription
— They cannot cancel or manipulate the persistence
operations.
@Subscriber
void beforeInsert(PreInsertEvent event) {
//do stuff
}
@alvaro_sanchez
Synchronous subscription
@Listener
void tagFunnyBooks(PreInsertEvent event) {
String title = event.getEntityAccess()
.getPropertyValue("title")
if(title?.contains("funny")) {
event.getEntityAccess()
.setProperty("title", "Humor - ${title}".toString())
}
}
@alvaro_sanchez
Spring events
— Disabled by default, for performance reasons.
— Enable them by setting grails.events.spring to true.
@Events(namespace="spring")
class MyService {
@Subscriber
void applicationStarted(ApplicationStartedEvent event) {
// fired when the application starts
}
@Subscriber
void servletRequestHandled(RequestHandledEvent event) {
// fired each time a request is handled
}
}
@alvaro_sanchez
Async GORM
@alvaro_sanchez
 Get started
— NOTE: drivers are still blocking. This just offloads it to
a different thread pool.
— Include compile "org.grails:grails-datastore-gorm-
async" in your build.
— Implement the AsyncEntity trait:
class Book implements AsyncEntity<Book> {
...
}
@alvaro_sanchez
The async namespace
Promise<Person> p1 = Person.async.get(1L)
Promise<Person> p2 = Person.async.get(2L)
List<Person> people = waitAll(p1, p2) //Blocks
Person.async.list().onComplete { List<Person> results ->
println "Got people = ${results}"
}
Promise<Person> person = Person.where {
lastName == "Simpson"
}.async.list()
@alvaro_sanchez
Async and the Hibernate session
— The Hibernate session is not concurrency safe.
— Objects returned from asynchronous queries will be
detached entities.
— This will fail:
Person p = Person.async.findByFirstName("Homer").get()
p.firstName = "Bart"
p.save()
@alvaro_sanchez
Async and the Hibernate session
— Entities need to be merged first with the session
bound to the calling thread
Person p = Person.async.findByFirstName("Homer").get()
p.merge()
p.firstName = "Bart"
p.save()
— Also, be aware that association lazy loading will not
work. Use eager queries / fetch joins / etc.
@alvaro_sanchez
Multiple async GORM calls
Promise<Person> promise = Person.async.task {
withTransaction {
Person person = findByFirstName("Homer")
person.firstName = "Bart"
person.save(flush:true)
}
}
Person updatedPerson = promise.get()
@alvaro_sanchez
Async models
import static grails.async.WebPromises.*
def index() {
tasks books: Book.async.list(),
totalBooks: Book.async.count(),
otherValue: {
// do hard work
}
}
@alvaro_sanchez
RxJava Support
@alvaro_sanchez
RxJava support
— Add org.grails.plugins:rxjava to your dependencies.
— You can then return rx.Observable's from controllers,
and Grails will:
1. Create a new asynchronous request
2. Spawn a new thread that subscribes to the
observable
3. When the observable emits a result, process the
result using the respond method.
@alvaro_sanchez
Demo
@alvaro_sanchez
Q & A
Álvaro Sánchez-Mariscal
@alvaro_sanchez

More Related Content

What's hot

BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019
BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019
BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019
TiLiu5
 
Cloud Computing: Overview and Examples
Cloud Computing: Overview and ExamplesCloud Computing: Overview and Examples
Cloud Computing: Overview and Examples
Eueung Mulyana
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
MongoDB
 
Alfresco Share - Recycle Bin Ideas
Alfresco Share - Recycle Bin IdeasAlfresco Share - Recycle Bin Ideas
Alfresco Share - Recycle Bin Ideas
AlfrescoUE
 
An introduction to MongoDB
An introduction to MongoDBAn introduction to MongoDB
An introduction to MongoDB
Universidade de São Paulo
 
Red hat cloud platforms
Red hat cloud platformsRed hat cloud platforms
Red hat cloud platforms
Giovanni Galloro
 
MySQL Atchitecture and Concepts
MySQL Atchitecture and ConceptsMySQL Atchitecture and Concepts
MySQL Atchitecture and Concepts
Tuyen Vuong
 
Mongodb introduction and_internal(simple)
Mongodb introduction and_internal(simple)Mongodb introduction and_internal(simple)
Mongodb introduction and_internal(simple)
Kai Zhao
 
GraphQL
GraphQLGraphQL
Orion Context Broker 1.15.0
Orion Context Broker 1.15.0Orion Context Broker 1.15.0
Orion Context Broker 1.15.0
Fermin Galan
 
How to migrate from Alfresco Search Services to Alfresco SearchEnterprise
How to migrate from Alfresco Search Services to Alfresco SearchEnterpriseHow to migrate from Alfresco Search Services to Alfresco SearchEnterprise
How to migrate from Alfresco Search Services to Alfresco SearchEnterprise
Angel Borroy López
 
DCEU 18: Dockerfile Best Practices
DCEU 18: Dockerfile Best PracticesDCEU 18: Dockerfile Best Practices
DCEU 18: Dockerfile Best Practices
Docker, Inc.
 
Android Studio Overview
Android Studio OverviewAndroid Studio Overview
Android Studio Overview
Salim Hosen
 
OrientDB for real & Web App development
OrientDB for real & Web App developmentOrientDB for real & Web App development
OrientDB for real & Web App development
Luca Garulli
 
Docker Compose by Aanand Prasad
Docker Compose by Aanand Prasad Docker Compose by Aanand Prasad
Docker Compose by Aanand Prasad
Docker, Inc.
 
Introduction to Github Actions
Introduction to Github ActionsIntroduction to Github Actions
Introduction to Github Actions
Knoldus Inc.
 
Android activity
Android activityAndroid activity
Android activity
Krazy Koder
 
An Introduction To Jenkins
An Introduction To JenkinsAn Introduction To Jenkins
An Introduction To Jenkins
Knoldus Inc.
 
OrientDB introduction - NoSQL
OrientDB introduction - NoSQLOrientDB introduction - NoSQL
OrientDB introduction - NoSQL
Luca Garulli
 
Ibm web sphere application server interview questions
Ibm web sphere application server interview questionsIbm web sphere application server interview questions
Ibm web sphere application server interview questions
praveen_guda
 

What's hot (20)

BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019
BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019
BÀI THÍ NGHIỆM SỐ XÂY DỰNG HIBERNATE CHO ỨNG DỤNG JAVA_10441312092019
 
Cloud Computing: Overview and Examples
Cloud Computing: Overview and ExamplesCloud Computing: Overview and Examples
Cloud Computing: Overview and Examples
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 
Alfresco Share - Recycle Bin Ideas
Alfresco Share - Recycle Bin IdeasAlfresco Share - Recycle Bin Ideas
Alfresco Share - Recycle Bin Ideas
 
An introduction to MongoDB
An introduction to MongoDBAn introduction to MongoDB
An introduction to MongoDB
 
Red hat cloud platforms
Red hat cloud platformsRed hat cloud platforms
Red hat cloud platforms
 
MySQL Atchitecture and Concepts
MySQL Atchitecture and ConceptsMySQL Atchitecture and Concepts
MySQL Atchitecture and Concepts
 
Mongodb introduction and_internal(simple)
Mongodb introduction and_internal(simple)Mongodb introduction and_internal(simple)
Mongodb introduction and_internal(simple)
 
GraphQL
GraphQLGraphQL
GraphQL
 
Orion Context Broker 1.15.0
Orion Context Broker 1.15.0Orion Context Broker 1.15.0
Orion Context Broker 1.15.0
 
How to migrate from Alfresco Search Services to Alfresco SearchEnterprise
How to migrate from Alfresco Search Services to Alfresco SearchEnterpriseHow to migrate from Alfresco Search Services to Alfresco SearchEnterprise
How to migrate from Alfresco Search Services to Alfresco SearchEnterprise
 
DCEU 18: Dockerfile Best Practices
DCEU 18: Dockerfile Best PracticesDCEU 18: Dockerfile Best Practices
DCEU 18: Dockerfile Best Practices
 
Android Studio Overview
Android Studio OverviewAndroid Studio Overview
Android Studio Overview
 
OrientDB for real & Web App development
OrientDB for real & Web App developmentOrientDB for real & Web App development
OrientDB for real & Web App development
 
Docker Compose by Aanand Prasad
Docker Compose by Aanand Prasad Docker Compose by Aanand Prasad
Docker Compose by Aanand Prasad
 
Introduction to Github Actions
Introduction to Github ActionsIntroduction to Github Actions
Introduction to Github Actions
 
Android activity
Android activityAndroid activity
Android activity
 
An Introduction To Jenkins
An Introduction To JenkinsAn Introduction To Jenkins
An Introduction To Jenkins
 
OrientDB introduction - NoSQL
OrientDB introduction - NoSQLOrientDB introduction - NoSQL
OrientDB introduction - NoSQL
 
Ibm web sphere application server interview questions
Ibm web sphere application server interview questionsIbm web sphere application server interview questions
Ibm web sphere application server interview questions
 

Similar to Asynchronous and event-driven Grails applications

Reactive microservices with Micronaut - GR8Conf EU 2018
Reactive microservices with Micronaut - GR8Conf EU 2018Reactive microservices with Micronaut - GR8Conf EU 2018
Reactive microservices with Micronaut - GR8Conf EU 2018
Alvaro Sanchez-Mariscal
 
Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#
Rainer Stropek
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
jnewmanux
 
Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018
Alvaro Sanchez-Mariscal
 
Marble Testing RxJS streams
Marble Testing RxJS streamsMarble Testing RxJS streams
Marble Testing RxJS streams
Ilia Idakiev
 
Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
Ryan Weaver
 
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Codemotion
 
Offline First with Service Worker
Offline First with Service WorkerOffline First with Service Worker
Offline First with Service Worker
Muhammad Samu
 
Asynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NETAsynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NET
Chris Dufour
 
Step By Step Guide For Buidling Simple Struts App
Step By Step Guide For Buidling Simple Struts AppStep By Step Guide For Buidling Simple Struts App
Step By Step Guide For Buidling Simple Struts App
Syed Shahul
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
Paweł Kowalczuk
 
Reliable Javascript
Reliable Javascript Reliable Javascript
Reliable Javascript
Glenn Stovall
 
High Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring BootHigh Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring Boot
Daniel Woods
 
PWA 與 Service Worker
PWA 與 Service WorkerPWA 與 Service Worker
PWA 與 Service Worker
Anna Su
 
JQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On VacayJQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On Vacay
Natasha Rooney
 
JQuery UK Service Workers Talk
JQuery UK Service Workers TalkJQuery UK Service Workers Talk
JQuery UK Service Workers Talk
Natasha Rooney
 
Access to User Activities - Activity Platform APIs
Access to User Activities - Activity Platform APIsAccess to User Activities - Activity Platform APIs
Access to User Activities - Activity Platform APIs
Atlassian
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
Sam Brannen
 
Spring boot
Spring boot Spring boot
Spring boot
Vinay Prajapati
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bits
jungkees
 

Similar to Asynchronous and event-driven Grails applications (20)

Reactive microservices with Micronaut - GR8Conf EU 2018
Reactive microservices with Micronaut - GR8Conf EU 2018Reactive microservices with Micronaut - GR8Conf EU 2018
Reactive microservices with Micronaut - GR8Conf EU 2018
 
Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018
 
Marble Testing RxJS streams
Marble Testing RxJS streamsMarble Testing RxJS streams
Marble Testing RxJS streams
 
Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
 
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
 
Offline First with Service Worker
Offline First with Service WorkerOffline First with Service Worker
Offline First with Service Worker
 
Asynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NETAsynchronous Programming in ASP.NET
Asynchronous Programming in ASP.NET
 
Step By Step Guide For Buidling Simple Struts App
Step By Step Guide For Buidling Simple Struts AppStep By Step Guide For Buidling Simple Struts App
Step By Step Guide For Buidling Simple Struts App
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Reliable Javascript
Reliable Javascript Reliable Javascript
Reliable Javascript
 
High Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring BootHigh Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring Boot
 
PWA 與 Service Worker
PWA 與 Service WorkerPWA 與 Service Worker
PWA 與 Service Worker
 
JQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On VacayJQuery UK February 2015: Service Workers On Vacay
JQuery UK February 2015: Service Workers On Vacay
 
JQuery UK Service Workers Talk
JQuery UK Service Workers TalkJQuery UK Service Workers Talk
JQuery UK Service Workers Talk
 
Access to User Activities - Activity Platform APIs
Access to User Activities - Activity Platform APIsAccess to User Activities - Activity Platform APIs
Access to User Activities - Activity Platform APIs
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
 
Spring boot
Spring boot Spring boot
Spring boot
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bits
 

More from Alvaro Sanchez-Mariscal

Serverless functions with Micronaut
Serverless functions with MicronautServerless functions with Micronaut
Serverless functions with Micronaut
Alvaro Sanchez-Mariscal
 
6 things you need to know about GORM 6
6 things you need to know about GORM 66 things you need to know about GORM 6
6 things you need to know about GORM 6
Alvaro Sanchez-Mariscal
 
Practical Spring Cloud
Practical Spring CloudPractical Spring Cloud
Practical Spring Cloud
Alvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016
Alvaro Sanchez-Mariscal
 
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring SecurityDesarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Alvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016
Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016
Alvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016
Alvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring SecurityCreating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring Security
Alvaro Sanchez-Mariscal
 
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Alvaro Sanchez-Mariscal
 
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Alvaro Sanchez-Mariscal
 
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015
Alvaro Sanchez-Mariscal
 
Ratpack 101 - GR8Conf 2015
Ratpack 101 - GR8Conf 2015Ratpack 101 - GR8Conf 2015
Ratpack 101 - GR8Conf 2015
Alvaro Sanchez-Mariscal
 
Ratpack 101 - GeeCON 2015
Ratpack 101 - GeeCON 2015Ratpack 101 - GeeCON 2015
Ratpack 101 - GeeCON 2015
Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices - Spring I/O 2015
Stateless authentication for microservices  - Spring I/O 2015Stateless authentication for microservices  - Spring I/O 2015
Stateless authentication for microservices - Spring I/O 2015
Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015
Alvaro Sanchez-Mariscal
 

More from Alvaro Sanchez-Mariscal (20)

Serverless functions with Micronaut
Serverless functions with MicronautServerless functions with Micronaut
Serverless functions with Micronaut
 
6 things you need to know about GORM 6
6 things you need to know about GORM 66 things you need to know about GORM 6
6 things you need to know about GORM 6
 
Practical Spring Cloud
Practical Spring CloudPractical Spring Cloud
Practical Spring Cloud
 
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
 
Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016
 
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring SecurityDesarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
 
Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016
 
Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
 
Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016
 
Creating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring SecurityCreating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring Security
 
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
 
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
 
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
 
Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015
 
Ratpack 101 - GR8Conf 2015
Ratpack 101 - GR8Conf 2015Ratpack 101 - GR8Conf 2015
Ratpack 101 - GR8Conf 2015
 
Ratpack 101 - GeeCON 2015
Ratpack 101 - GeeCON 2015Ratpack 101 - GeeCON 2015
Ratpack 101 - GeeCON 2015
 
Stateless authentication for microservices - Spring I/O 2015
Stateless authentication for microservices  - Spring I/O 2015Stateless authentication for microservices  - Spring I/O 2015
Stateless authentication for microservices - Spring I/O 2015
 
Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015
 

Recently uploaded

OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
Gerardo Pardo-Castellote
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
Peter Muessig
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 

Recently uploaded (20)

OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 

Asynchronous and event-driven Grails applications

  • 1. Async and event-driven Grails applications Álvaro Sánchez-Mariscal @alvaro_sanchez
  • 2. About me — Coming from Madrid ! — Developer since 2001 (Java / Spring stack). — Grails fanboy since v0.4. — Working @ OCI since 2015: Groovy, Grails & Micronaut! — Father since 2017! " @alvaro_sanchez
  • 4. Grails Async Framework — https://async.grails.org — Introduced in Grails 2.3 with the Promise API. Spun- off in Grails 3.3 — Supports different async libraries: GPars, RxJava and Reactor. — Application events, Spring events, GORM events. — Async GORM. @alvaro_sanchez
  • 5. Grails Async Framework — Server Sent Events. — RxGORM. — Async request/response processing. — Servlet 3.0 async support. @alvaro_sanchez
  • 6.  Ge"ing started — Add the dependency in build.gradle: runtime "org.grails.plugins:async" — Check the Grails plugin page for more information: http://plugins.grails.org/plugin/grails/async @alvaro_sanchez
  • 8.  Servlet 3.0 — Spec'ed in 2009! ! — Allows offloading of blocking operations to a different thread. — Implement grails.async.web.AsyncController to get started. — Call startAsync() to get the javax.servlet.AsyncContext — When done, call complete() or dispatch() @alvaro_sanchez
  • 10.  Advanced usage ctx.addListener(new AsyncListener() { void onStartAsync(AsyncEvent event) throws IOException { } void onComplete(AsyncEvent event) throws IOException { } void onTimeout(AsyncEvent event) throws IOException { } void onError(AsyncEvent event) throws IOException { } }) ctx.timeout = 5_000 @alvaro_sanchez
  • 12. Grails Promise API — Builds on top of java.util.concurrent.Future. — grails.async.Promises helps you to create Promise<T> instances. — In controllers, better use grails.async.web.WebPromises (Servlet 3.0 Async under the covers) — PromiseFactory allows pluggable implementations. @alvaro_sanchez
  • 13. PromiseFactory API — CachedThreadPoolPromiseFactory (default): unbound thread pool. — GparsPromiseFactory: if org:grails:grails-async-gpars dependecy is on the classpath. — RxPromiseFactory: if either org.grails:grails-async- rxjava or org.grails:grails-async-rxjava2 are on the classpath. @alvaro_sanchez
  • 14. PromiseFactory API — SynchronousPromiseFactory: useful for unit testing. import org.grails.async.factory.* import grails.async.* Promises.promiseFactory = new SynchronousPromiseFactory() @alvaro_sanchez
  • 16. PromiseList import grails.async.* PromiseList<Integer> list = new PromiseList<>() list << { 2 * 2 } list << { 4 * 4 } list << { 8 * 8 } list.onComplete { List<Integer> results -> assert [4,16,64] == results } @alvaro_sanchez
  • 17.  PromiseMap import static grails.async.Promises.* PromiseMap promiseMap = tasks one: { 2 * 2 }, two: { 4 * 4}, three:{ 8 * 8 } assert [one:4,two:16,three:64] == promiseMap.get() @alvaro_sanchez
  • 18. @DelegateAsync import grails.async.* class BookService { List<Book> findBooks(String title) { ... } } class AsyncBookService { @DelegateAsync BookService bookService } @alvaro_sanchez
  • 19. @DelegateAsync import grails.async.* class BookService { List<Book> findBooks(String title) { ... } } class AsyncBookService { //Equivalent Promise<List<Book>> findBooks(String title) { task { bookService.findBooks(title) } } } @alvaro_sanchez
  • 20. Using the service @Autowired AsyncBookService asyncBookService def findBooks(String title) { asyncBookService.findBooks(title) .onComplete { List<Book> results -> render "Books = ${results}" } } @alvaro_sanchez
  • 22. Grails Events abstraction — Add the dependency in build.gradle: runtime "org.grails.plugins:events" — By default Grails creates an EventBus based off of the currently active PromiseFactory. — Or you can use: — org.grails:grails-events-gpars — org.grails:grails-events-rxjava — org.grails:grails-events-rxjava2 @alvaro_sanchez
  • 23. Publishing events — With the @Publisher annotation: class SumService { @Publisher int sum(int a, int b) { a + b } } @alvaro_sanchez
  • 24. Publishing events — With the EventPublisher API: class SumService implements EventPublisher { int sum(int a, int b) { int result = a + b notify("sum", result) return result } } @alvaro_sanchez
  • 25. Subscribing to events — With the @Subscriber annotation: class TotalService { AtomicInteger total = new AtomicInteger(0) @Subscriber void onSum(int num) { total.addAndGet(num) } } @alvaro_sanchez
  • 26. Subscribing to events — With the EventBusAware API: class TotalService implements EventBusAware { AtomicInteger total = new AtomicInteger(0) @PostConstruct void init() { eventBus.subscribe("sum") { int num -> total.addAndGet(num) } } } @alvaro_sanchez
  • 27. GORM events — DatastoreInitializedEvent — PostDeleteEvent — PostInsertEvent — PostLoadEvent — PostUpdateEvent @alvaro_sanchez
  • 28. GORM events — PreDeleteEvent — PreInsertEvent — PreLoadEvent — PreUpdateEvent — SaveOrUpdateEvent — ValidationEvent @alvaro_sanchez
  • 29. Asynchronous subscription — They cannot cancel or manipulate the persistence operations. @Subscriber void beforeInsert(PreInsertEvent event) { //do stuff } @alvaro_sanchez
  • 30. Synchronous subscription @Listener void tagFunnyBooks(PreInsertEvent event) { String title = event.getEntityAccess() .getPropertyValue("title") if(title?.contains("funny")) { event.getEntityAccess() .setProperty("title", "Humor - ${title}".toString()) } } @alvaro_sanchez
  • 31. Spring events — Disabled by default, for performance reasons. — Enable them by setting grails.events.spring to true. @Events(namespace="spring") class MyService { @Subscriber void applicationStarted(ApplicationStartedEvent event) { // fired when the application starts } @Subscriber void servletRequestHandled(RequestHandledEvent event) { // fired each time a request is handled } } @alvaro_sanchez
  • 33.  Get started — NOTE: drivers are still blocking. This just offloads it to a different thread pool. — Include compile "org.grails:grails-datastore-gorm- async" in your build. — Implement the AsyncEntity trait: class Book implements AsyncEntity<Book> { ... } @alvaro_sanchez
  • 34. The async namespace Promise<Person> p1 = Person.async.get(1L) Promise<Person> p2 = Person.async.get(2L) List<Person> people = waitAll(p1, p2) //Blocks Person.async.list().onComplete { List<Person> results -> println "Got people = ${results}" } Promise<Person> person = Person.where { lastName == "Simpson" }.async.list() @alvaro_sanchez
  • 35. Async and the Hibernate session — The Hibernate session is not concurrency safe. — Objects returned from asynchronous queries will be detached entities. — This will fail: Person p = Person.async.findByFirstName("Homer").get() p.firstName = "Bart" p.save() @alvaro_sanchez
  • 36. Async and the Hibernate session — Entities need to be merged first with the session bound to the calling thread Person p = Person.async.findByFirstName("Homer").get() p.merge() p.firstName = "Bart" p.save() — Also, be aware that association lazy loading will not work. Use eager queries / fetch joins / etc. @alvaro_sanchez
  • 37. Multiple async GORM calls Promise<Person> promise = Person.async.task { withTransaction { Person person = findByFirstName("Homer") person.firstName = "Bart" person.save(flush:true) } } Person updatedPerson = promise.get() @alvaro_sanchez
  • 38. Async models import static grails.async.WebPromises.* def index() { tasks books: Book.async.list(), totalBooks: Book.async.count(), otherValue: { // do hard work } } @alvaro_sanchez
  • 40. RxJava support — Add org.grails.plugins:rxjava to your dependencies. — You can then return rx.Observable's from controllers, and Grails will: 1. Create a new asynchronous request 2. Spawn a new thread that subscribes to the observable 3. When the observable emits a result, process the result using the respond method. @alvaro_sanchez
  • 42. Q & A Álvaro Sánchez-Mariscal @alvaro_sanchez