This makes it critical that if you do any blocking I/O operations (for example interactions with Hibernate/JPA or JDBC) that you offload those tasks to a separate thread pool that does not block the Event loop.

    For example the following configuration will configure the I/O thread pool as a fixed thread pool with 75 threads (similar to what a traditional blocking server such as Tomcat uses in the thread per request model):

    Configuring the IO thread pool

    Using @ExecuteOn

    1. import io.micronaut.scheduling.TaskExecutors;
    2. import io.micronaut.scheduling.annotation.ExecuteOn;
    3. @Controller("/executeOn/people")
    4. public class PersonController {
    5. private final PersonService personService;
    6. PersonController(
    7. PersonService personService) {
    8. this.personService = personService;
    9. }
    10. @Get("/{name}")
    11. @ExecuteOn(TaskExecutors.IO) (1)
    12. Person byName(String name) {
    13. return personService.findByName(name);
    14. }

    Using @ExecuteOn

    Using @ExecuteOn

    1. import io.micronaut.http.annotation.*
    2. import io.micronaut.scheduling.annotation.ExecuteOn
    3. @Controller("/executeOn/people")
    4. class PersonController (private val personService: PersonService) {
    5. @Get("/{name}")
    6. @ExecuteOn(TaskExecutors.IO) (1)
    7. fun byName(name: String): Person {
    8. return personService.findByName(name)
    9. }
    10. }

    An alternative to the annotation is to use the facility provided by the reactive library you have chosen. RxJava for example features a subscribeOn method which allows you to alter which thread executes user code. For example:

    RxJava subscribeOn Example

    RxJava subscribeOn Example

    1. import io.micronaut.http.annotation.*
    2. import io.micronaut.scheduling.TaskExecutors
    3. import io.reactivex.*
    4. import io.reactivex.schedulers.Schedulers
    5. import javax.inject.Named
    6. import java.util.concurrent.ExecutorService
    7. private final Scheduler scheduler
    8. private final PersonService personService
    9. PersonController(
    10. @Named(TaskExecutors.IO) ExecutorService executorService, (1)
    11. PersonService personService) {
    12. this.scheduler = Schedulers.from(executorService)
    13. this.personService = personService
    14. }
    15. @Get("/{name}")
    16. Single<Person> byName(String name) {
    17. return Single.fromCallable({ -> (2)
    18. personService.findByName(name)
    19. }).subscribeOn(scheduler) (3)
    20. }
    21. }