SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

Rails SQL Injection Examplesの紹介
Rails SQL Injection Examplesの紹介Rails SQL Injection Examplesの紹介
Rails SQL Injection Examplesの紹介
Hiroshi Tokumaru
 

Was ist angesagt? (20)

C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
 
Gated-ViGAT
Gated-ViGATGated-ViGAT
Gated-ViGAT
 
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
 
SPAのルーティングの話
SPAのルーティングの話SPAのルーティングの話
SPAのルーティングの話
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Async Programming in C# 5
Async Programming in C# 5Async Programming in C# 5
Async Programming in C# 5
 
CORS - Enable Alfresco for CORS
CORS - Enable Alfresco for CORSCORS - Enable Alfresco for CORS
CORS - Enable Alfresco for CORS
 
Rails SQL Injection Examplesの紹介
Rails SQL Injection Examplesの紹介Rails SQL Injection Examplesの紹介
Rails SQL Injection Examplesの紹介
 
HDFS vs. MapR Filesystem
HDFS vs. MapR FilesystemHDFS vs. MapR Filesystem
HDFS vs. MapR Filesystem
 
golang profiling の基礎
golang profiling の基礎golang profiling の基礎
golang profiling の基礎
 
ガード節を使おう
ガード節を使おうガード節を使おう
ガード節を使おう
 
Office アドイン ハンズオン
Office アドイン ハンズオンOffice アドイン ハンズオン
Office アドイン ハンズオン
 
GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢
GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢
GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢
 
Real-Time Spark: From Interactive Queries to Streaming
Real-Time Spark: From Interactive Queries to StreamingReal-Time Spark: From Interactive Queries to Streaming
Real-Time Spark: From Interactive Queries to Streaming
 
BASEでデータ処理の幅を広げよう
BASEでデータ処理の幅を広げようBASEでデータ処理の幅を広げよう
BASEでデータ処理の幅を広げよう
 
ステップ バイ ステップでShareFile を試す
ステップ バイ ステップでShareFile を試すステップ バイ ステップでShareFile を試す
ステップ バイ ステップでShareFile を試す
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
 
Versionskontrolle mit Git
Versionskontrolle mit GitVersionskontrolle mit Git
Versionskontrolle mit Git
 

Ähnlich wie Asynchronous and event-driven Grails applications

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
 

Ähnlich wie 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
 

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Kürzlich hochgeladen (20)

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 

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