////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

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

To do so your should first implement the `grails.async.web.AsyncController` trait in your controller:

[source,groovy]
----
import grails.async.web.*

...
class BookController implements AsyncController {
    ...
}
----

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:

[source,groovy]
----
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:

[source,groovy]
----
def index() {
    def ctx = startAsync()
    ctx.start {
        // do working
        ...
        // render view
        ctx.dispatch()
    }
}
----
