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
import io.micronaut.scheduling.TaskExecutors;
import io.micronaut.scheduling.annotation.ExecuteOn;
@Controller("/executeOn/people")
public class PersonController {
private final PersonService personService;
PersonController(
PersonService personService) {
this.personService = personService;
}
@Get("/{name}")
@ExecuteOn(TaskExecutors.IO) (1)
Person byName(String name) {
return personService.findByName(name);
}
Using @ExecuteOn
Using @ExecuteOn
import io.micronaut.http.annotation.*
import io.micronaut.scheduling.annotation.ExecuteOn
@Controller("/executeOn/people")
class PersonController (private val personService: PersonService) {
@Get("/{name}")
@ExecuteOn(TaskExecutors.IO) (1)
fun byName(name: String): Person {
return personService.findByName(name)
}
}
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
import io.micronaut.http.annotation.*
import io.micronaut.scheduling.TaskExecutors
import io.reactivex.*
import io.reactivex.schedulers.Schedulers
import javax.inject.Named
import java.util.concurrent.ExecutorService
private final Scheduler scheduler
private final PersonService personService
PersonController(
@Named(TaskExecutors.IO) ExecutorService executorService, (1)
PersonService personService) {
this.scheduler = Schedulers.from(executorService)
this.personService = personService
}
@Get("/{name}")
Single<Person> byName(String name) {
return Single.fromCallable({ -> (2)
personService.findByName(name)
}).subscribeOn(scheduler) (3)
}
}