11 Asynchronous Programming 3.1.4

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 11 Asynchronous Programming - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 3.1.4 ## Table of Contents # 11 Asynchronous Programming With modern hardware featuring multiple cores, many programming languages have been adding asynchronous, parallel programming APIs, Groovy being no exception. The excellent GPars project features a whole range of different APIs for asynchronous programming techniques including actors, promises, STM and data flow concurrency. Added Grails 2.3, the Async features of Grails aim to simplify concurrent programming within the framework and include the concept of Promises and a unified event model. ## 11.1 Promises A Promise is a concept being embraced by many concurrency frameworks. They are similar to `java.util.concurrent.Future` instances, but include a more user friendly exception handling model, useful features like chaining and the ability to attach listeners. ### Promise Basics In Grails the `grails.async.Promises` class provides the entry point to the Promise API:
    import static grails.async.Promises.*
To create promises you can use the `task` method, which returns an instance of the `grails.async.Promise` interface:
    def p1 = task { 2 * 2 }
    def p2 = task { 4 * 4 }
    def p3 = task { 8 * 8 }
    assert [4,16,64] == waitAll(p1, p2, p3)
The `waitAll` method waits synchronously, blocking the current thread, for all of the concurrent tasks to complete and returns the results. If you prefer not to block the current thread you can use the `onComplete` method:
    onComplete([p1,p2,p3]) { List results ->
       assert [4,16,64] == results
    }
The `waitAll` method will throw an exception if an error occurs executing one of the promises. The originating exception will be thrown. The `onComplete` method, however, will simply not execute the passed closure if an exception occurs. You can register an `onError` listener if you wish to handle exceptions without blocking:
    onError([p1,p2,p3]) { Throwable t ->
       println "An error occured ${t.message}"
    }
If you have just a single long running promise then the `grails.async.Promise` interface provides a similar API on the promise itself. For example:

    import static java.util.concurrent.TimeUnit.*
    import static grails.async.Promises.*Promise p = task {
    	// Long running task
    }
    p.onError { Throwable err ->
    	println "An error occured ${err.message}"
    }
    p.onComplete { result ->
        println "Promise returned $result"
    }
    // block until result is called
    def result = p.get()
    // block for the specified time
    def result = p.get(1,MINUTES)
### Promise Chaining It is possible to chain several promises and wait for the chain to complete using the `then` method:

    final polish = { … }
    final transform = { … }
    final save = { … }
    final notify = { … }Promise promise = task {
        // long running task
    }
    promise.then polish then transform then save then {
    	// notify end result
    }
If an exception occurs at any point in the chain it will be propagated back to the caller and the next step in the chain will not be called. ### Promise Lists and Maps Grails' async API also features the concept of a promise lists and maps. These are represented by the `grails.async.PromiseList` and `grails.async.PromiseMap` classes respectively. The easiest way to create a promise list or map is via the `tasks` method of the `Promises` class:

    import static grails.async.Promises.*def promiseList = tasks([{ 2 * 2 }, { 4 * 4}, { 8 * 8 }])assert [4,16,64] == promiseList.get()
The `tasks` method, when passed a list of closures, returns a `PromiseList`. You can also construct a `PromiseList` manually:

    import grails.async.*def list = new PromiseList()
    list << { 2 * 2 }
    list << { 4 * 4 }
    list << { 8 * 8 }
    list.onComplete { List results ->
      assert [4,16,64] == results
    }
The `PromiseList` class does not implement the java.util.List interface, but instead returns a java.util.List from the get() method Working with `PromiseMap` instances is largely similar. Again you can either use the `tasks` method:

    import static grails.async.Promises.*def promiseList = tasks one:{ 2 * 2 },
                            two:{ 4 * 4},
                            three:{ 8 * 8 }assert [one:4,two:16,three:64] == promiseList.get()
Or construct a `PromiseMap` manually:

    import grails.async.*def map = new PromiseMap()
    map['one'] = { 2 * 2 }
    map['two'] = { 4 * 4 }
    map['three'] = { 8 * 8 }
    map.onComplete { Map results ->
      assert [one:4,two:16,three:64] == results
    }
### Promise Factories The `Promises` class uses a `grails.async.PromiseFactory` instance to create `Promise` instances. The default implementation uses the GPars concurrency library and is called `org.grails.async.factory.gpars.GparsPromiseFactory`, however it is possible to swap implementations by setting the `Promises.promiseFactory` variable. One common use case for this is unit testing, typically you do not want promises to execute asynchronously during unit tests, as this makes tests harder to write. For this purpose Grails ships with a `org.grails.async.factory.SynchronousPromiseFactory` instance that makes it easier to test promises:

    import org.grails.async.factory.*
    import grails.async.*Promises.promiseFactory = new SynchronousPromiseFactory()
Grails also has a `org.grails.async.factory.reactor.ReactorPromiseFactory` which allows you to use the Reactor. You can use it by settings `Promises.promiseFactory` as given above. Using the `PromiseFactory` mechanism it is theoretically possible to plug in other concurrency libraries into the Grails framework. For this you need to override the two interfaces `grails.async.Promise` and `grails.async.PromiseFactory`. ### DelegateAsync Transformation It is quite common to require both synchronous and asynchronous versions of the same API. Developing both can result in a maintenance problem as typically the asynchronous API would simply delegate to the synchronous version. The `DelegateAsync` transformation is designed to mitigate this problem by transforming any synchronous API into an asynchronous one. For example, consider the following service:
    class BookService {
        List<Book> findBooks(String title) {
          // implementation
        }
    }
The `findBooks` method executes synchronously in the same thread as the caller. To make an asynchronous version of this API you can define another class as follows:

    import grails.async.*class AsyncBookService {
       @DelegateAsync BookService bookService
    }
The `DelegateAsync` transformation will automatically add a new method that looks like the following to the `AsyncBookService` class:
    Promise<List<Book>> findBooks(String title) {
        Promises.task {
           bookService.findBooks(title)
        }
    }
As you see the transform adds equivalent methods that return a Promise and execute asynchronously. The `AsyncBookService` can then be injected into other controllers and services and used as follows:
    AsyncBookService asyncBookService
    def findBooks(String title) {
        asyncBookService.findBooks(title)
           .onComplete { List results ->
              println "Books = ${results}"
           }
    }
## 11.2 Events Grails 3.0 introduces a new Events API based on Reactor. All services and controllers in Grails 3.0 implement the Events trait. The `Events` trait allows the ability to consume and publish events that are handled by Reactor. The default Reactor configuration utilises a thread pool backed event bus. You can however configure Reactor within `application.yml`, for example:
    reactor:
        dispatchers:
            default: myExecutor
            myExecutor:
                type: threadPoolExecutor
                size: 5
                backlog: 2048
## 11.2.1 Consuming Events There are several ways to consume an event. As mentioned previously services and controllers implement the Events trait. The `Events` trait provides several methods to register event consumers. For example:
    on("myEvent") {
        println "Event fired!"
    }
Note that if you wish a class (other than a controller or service) to be an event consumer you simply have to implement the `Events` trait and ensure the class is registered as a Spring bean. For example given the following class:

    import grails.events.*
    import javax.annotation.*class MyClass implements Events {	@PostConstruct
    	void init() {
    		on("myEvent") {
    		    println "Event fired!"
    		}
    	}
    }
You can override `doWithSpring` in your `Application` class to register it as a Spring bean (or annotate it with `Component`):
    Closure doWithSpring() {
            {->
        		myClass(MyClass)
            }
        }
## 11.2.2 Event Notification The `Events` trait also provides methods for notifying of events. For example:
    notify "myEvent", "myData"
    sendAndReceive "myEvent", "myData", {
        println "Got response!"
    }
## 11.2.3 Reactor Spring Annotations Reactor provides a few useful annotations that can be used for declaratively consuming events in a Grails service. To declare an event consumer use the `Consumer` annotation:

    import reactor.spring.context.annotation.*@Consumer
    class MyService {}
Then to register to listen for an event use the `Selector` annotation:

    import reactor.spring.context.annotation.*@Consumer
    class MyService {
    	@Selector('my.event')
    	void myEventListener(Object data) {
    		println "GOT EVENT $data"
    	}
    }
## 11.2.4 Events from GORM GORM defines a number of useful events that you can listen for. Each event is translated into a key that starts with `gorm:`. For example:

    import org.grails.datastore.mapping.engine.event.*
    ...on("gorm:preInsert") { PreInsertEvent event ->
    	println "GOT EVENT $event"
    }
These events are triggered asynchronously, and so cannot cancel or manipulate the persistence operations. If you want to do that see the section on Events & Auto Timestamping in the GORM docs ## 11.2.5 Events from Spring Spring also fires a number of useful events. All events in the `org.springframework` package are prefixed with `spring:`. For example:

    import org.springframework.web.context.support.*
    import org.springframework.boot.context.event.*
    ...on("spring:applicationStarted") { ApplicationStartedEvent event ->
    	// fired when the application starts
    }on("spring:servletRequestHandled") { RequestHandledEvent event ->
    	// fired each time a request is handled
    }
## 11.3 Asynchronous GORM Since Grails 2.3, GORM features an asynchronous programming model that works across all supported datastores (Hibernate, MongoDB etc.). Although GORM executes persistence operations asynchronously, these operations still block as the underlying database drivers are not asynchronous. Asynchornous GORM is designed to allow you to isolate these blocking operations onto a separate thread you can scale and control allowing your controller layer to remain non-blocking. ### Async Namespace The Asynchronous GORM API is available on every domain class via the `async` namespace. For example, the following code listing reads 3 objects from the database asynchronously:

    import static grails.async.Promises.*def p1 = Person.async.get(1L)
    def p2 = Person.async.get(2L)
    def p3 = Person.async.get(3L)
    def results = waitAll(p1, p2, p3)
Using the `async` namespace, all the regular GORM methods are available (even dynamic finders), but instead of executing synchronously, the query is run in the background and a `Promise` instance is returned. The following code listing shows a few common examples of GORM queries executed asynchronously:

    import static grails.async.Promises.*Person.async.list().onComplete { List results ->
      println "Got people = ${results}"
    }
    def p = Person.async.getAll(1L, 2L, 3L)
    List results = p.get()def p1 = Person.async.findByFirstName("Homer")
    def p2 = Person.async.findByFirstName("Bart")
    def p3 = Person.async.findByFirstName("Barney")
    results = waitAll(p1, p2, p3)
### Async and the Session When using GORM async each promise is executed in a different thread. Since the Hibernate session is not concurrency safe, a new session is bound per thread. This is an important consideration when using GORM async (particularly with Hibernate as the persistence engine). The objects returned from asynchronous queries will be detached entities. This means you cannot save objects returned from asynchronous queries without first merging them back into session. For example the following will not work:
    def promise = Person.async.findByFirstName("Homer")
    def person = promise.get()
    person.firstName = "Bart"
    person.save()
Instead you need to merge the object with the session bound to the calling thread. The above code needs to be written as:
    def promise = Person.async.findByFirstName("Homer")
    def person = promise.get()
    person.merge()
    person.firstName = "Bart"
Note that `merge()` is called first because it may refresh the object from the cache or database, which would result in the change being lost. In general it is not recommended to read and write objects in different threads and you should avoid this technique unless absolutely necessary. Finally, another issue with detached objects is that association lazy loading will not work and you will encounter `LazyInitializationException` errors if you do so. If you plan to access the associated objects of those returned from asynchronous queries you should use eager queries (which is recommended anyway to avoid N+1 problems). ### Multiple Asynchronous GORM calls As discussed in the previous section you should avoid reading and writing objects in different threads as merging tends to be inefficient. However, if you wish to do more complex GORM work asynchronously then the GORM async namespace provides a `task` method that makes this possible. For example:

    def promise = Person.async.task {
        withTransaction {
           def person = findByFirstName("Homer")
           person.firstName = "Bart"
           person.save(flush:true)
        }
    }Person updatedPerson = promise.get()
Note that the GORM `task` method differs from the static `Promises.task` method in that it deals with binding a new session to the asynchronous thread for you. If you do not use the GORM version and do asynchronous work with GORM then you need to do this manually. Example:

    import static grails.async.Promises.*def promise = task {
        Person.withNewSession {
        	// your logic here
        }
    }
### Async DetachedCriteria The `DetachedCriteria` class also supports the `async` namespace. For example you can do the following:

    DetachedCriteria query = Person.where {
        lastName == "Simpson"
    }def promise = query.async.list()
## 11.4 Asynchronous Request Handling If you are deploying to a Servlet 3.0 container such as Tomcat 7 and above then it is possible to deal with responses asynchronously. In general for controller actions that execute quickly there is little benefit in handling requests asynchronously. However, for long running controller actions it is extremely beneficial. The reason being that with an asynchronous / non-blocking response, the one thread == one request == one response relationship is broken. The container can keep a client response open and active, and at the same time return the thread back to the container to deal with another request, improving scalability. For example, if you have 70 available container threads and an action takes a minute to complete, if the actions are not executed in a non-blocking fashion the likelihood of all 70 threads being occupied and the container not being able to respond is quite high and you should consider asynchronous request processing. Since Grails 2.3, Grails features a simplified API for creating asynchronous responses built on the `Promise` mechanism discussed previously. The implementation is based on Servlet 3.0 async. So, to enable the async features you need to set your servlet target version to 3.0 in application.yml:
    grails:
        servlet:
            version: 3.0
#### Async Models A typical activity in a Grails controller is to produce a model (a map of key/value pairs) that can be rendered by a view. If the model takes a while to produce then the server could arrive at a blocking state, impacting scalability. You tell Grails to build the model asynchronously by returning a `grails.async.PromiseMap` via the `Promises.tasks` method:
    import static grails.async.Promises.*
    …
    def index() {
       tasks books: Book.async.list(),
             totalBooks: Book.async.count(),
             otherValue: {
               // do hard work
             }
    }
Grails will handle the response asynchronously, waiting for the promises to complete before rendering the view. The equivalent synchronous action of the above is:
    def index() {
        def otherValue = …
    	[ books: Book.list() ,
    	  totalBooks: Book.count(),
    	  otherValue: otherValue  ]
    }
You can even render different view by passing the `PromiseMap` to the `model` attribute of the `render` method:
    import static grails.async.Promises.*
    …
    def index() {
       render view:"myView", model: tasks( one:{ 2 * 2 },
                                           two:{ 3 * 3 } )
    }
#### Async Response Rendering You can also write to the response asynchronously using promises in Grails 2.3 and above:

    import static grails.async.Promises.*
    class StockController {    def stock(String ticker) {
           task {
               ticker = ticker ?: 'GOOG'
               def url = new URL("http://download.finance.yahoo.com/d/quotes.csv?s=${ticker}&f=nsl1op&e=.csv")
               Double price = url.text.split(',')[-1] as Double
               render "ticker: $ticker, price: $price"
           }
        }
    }
The above example using Yahoo Finance to query stock prices, executing asynchronously and only rendering the response once the result has been obtained. This is done by returning a `Promise` instance from the controller action. If the Yahoo URL is unresponsive the original request thread will not be blocked and the container will not become unresponsive. ## 11.5 Servlet 3.0 Async In addition to the higher level async features discussed earlier in the section, you can access the raw Servlet 3.0 asynchronous API from a Grails application. #### Servlet 3.0 Asynchronous Rendering You can render content (templates, binary data etc.) in an asynchronous manner by calling the `startAsync` method which returns an instance of the Servlet 3.0 `AsyncContext`. Once you have a reference to the `AsyncContext` you can use Grails' regular render method to render content:
    def index() {
        def ctx = startAsync()
        ctx.start {
            new Book(title:"The Stand").save()
            render template:"books", model:[books:Book.list()]
            ctx.complete()
        }
    }
Note that you must call the `complete()` method to terminate the connection. #### Resuming an Async Request You resume processing of an async request (for example to delegate to view rendering) by using the `dispatch` method of the `AsyncContext` class:
    def index() {
        def ctx = startAsync()
        ctx.start {
            // do working
            …
            // render view
            ctx.dispatch()
        }
    }
| Quick Reference (hide)