== Execution Model

Jooby is a flexible performant microframework providing both blocking and non-blocking APIs for 
building web applications in Java and Kotlin.

In this chapter we are going to learn about Jooby execution model, more specifically:

- Execute code on the *event loop*

- Safely execution of blocking code

- Working with non-blocking types, like: `CompletableFuture`, Reactive Streams, Kotlin Coroutines, etc.

=== Mode

==== Event Loop

The javadoc:ExecutionMode[EVENT_LOOP] mode allows us to run a route handler from the
*event loop* (a.k.a as non-blocking mode).

.Java
[source,java,role="primary"]
----
import static io.jooby.ExecutionMode.EVENT_LOOP;
import static io.jooby.Jooby.runApp;

public class App extends Jooby {

  {
    get("/", ctx -> "I'm non-blocking!" );
  }

  public static void main(String[] args) {
    runApp(args, EVENT_LOOP, App::new);
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.ExecutionMode.EVENT_LOOP
import io.jooby.Jooby.runApp

fun main(args: Array<String>) {
  runApp(args, EVENT_LOOP) {
    get("/") { "I'm non-blocking!" }
  }
}
----

The javadoc:ExecutionMode[EVENT_LOOP] mode is the more advanced execution mode and requires you carefully
design and implement your application due to that *BLOCKING IS NOT ALLOWED*

What if you need to block?

The javadoc:Router[dispatch, java.lang.Runnable] operator moves execution to a *worker executor* which 
allows to do *blocking calls*:

.Java
[source,java,role="primary"]
----
import static io.jooby.ExecutionMode.EVENT_LOOP;
import static io.jooby.Jooby.runApp;

public class App extends Jooby {

  {
    get("/", ctx -> {
      return "I'm non-blocking!";
    });
  
    dispatch(() -> {
      // All the routes defined here are allowed to block:

      get("/db-list", ctx -> {
        /** Safe to block! */
        Object result = ...; // Remote service, db call, etc..
        return result;
      });
  
    });
  }

  public static void main(String[] args) {
    runApp(args, EVENT_LOOP, App::new);
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.ExecutionMode.EVENT_LOOP
import io.jooby.Jooby.runApp

fun main(args: Array<String>) {
  runApp(args, EVENT_LOOP) {

    get("/") {
      "I'm non-blocking!"
    }
  
    dispatch {
      // All the routes defined here are allowed to block:
  
      get("/db-list") {
        /** Safe to block! */
        val result = ...; // Remote service, db call, etc..
        result
      }
  
    }
  }
}
----

By default, the javadoc:Router[dispatch, java.lang.Runnable] operator moves execution to the *server
worker executor* (executor provided by web server).

You can provide your own *worker executor* at application level or at dispatch level: 

.Java
[source,java,role="primary"]
----
import static io.jooby.ExecutionMode.EVENT_LOOP;
import static io.jooby.Jooby.runApp;

public class App extends Jooby {

  {
    // Application level executor
    worker(Executors.newCachedThreadPool());
  
    // Dispatch to application level executor which is cached thread pool
    dispatch(() -> {
      ...
    });
    
    // Dispatch to a explicit executor
    Executor cpuIntensive = Executors.newSingleThreadExecutor();
    dispatch(cpuIntesive, () -> {
      ...
    });
  }

  public static void main(String[] args) {
    runApp(args, EVENT_LOOP, App:new);
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.ExecutionMode.EVENT_LOOP
import io.jooby.Jooby.runApp

fun main(args: Array<String>) {
  runApp(args, EVENT_LOOP) {
  
    // Application level executor
    worker(Executors.newCachedThreadPool())
  
    // Dispatch to application level executor which is cached thread pool
    dispatch {
      ...
    }
    
    // Dispatch to a explicit executor
    Executor cpuIntensive = Executors.newSingleThreadExecutor()
    dispatch(cpuIntesive) {
      ...
    }
  }
}
----

==== Worker

The javadoc:ExecutionMode[WORKER] mode allows us to do blocking calls from a route handler (a.k.a blocking mode).
You just write code without worrying about blocking calls.

.Java
[source, java,role="primary"]
----
import static io.jooby.ExecutionMode.WORKER;
import static io.jooby.Jooby.runApp;

public class App extends Jooby {

  {
    get("/", ctx -> {
      /** Safe to block! */
      Object result = // Remote service, db call, etc..
      return result;
    });
  }

  public static void main(String[] args) {
    runApp(args, WORKER, App::new);
  }
}
----

.Kotlin
[source, kotlin,role="secondary"]
----
import io.jooby.ExecutionMode.WORKER
import io.jooby.Jooby.runApp

fun main(args: Array<String>) {
  runApp(args, WORKER) {

    get("/") {
      /** Safe to block! */
      val result = ...;// Remote service, db call, etc..
      result
    }
  }
}
----

Like with javadoc:ExecutionMode[EVENT_LOOP] mode, you can provide your own worker executor:

.Java
[source,java,role="primary"]
----
import static io.jooby.ExecutionMode.WORKER;
import static io.jooby.Jooby.runApp;

public class App extends Jooby {

  {
    worker(Executors.newCachedThreadPool());
        
    get("/", ctx -> {
      /** Safe to block from cached thread pool! */
      Object result = // Remote service, db call, etc..
      return result;
    });
  }

  public static void main(String[] args) {
    runApp(args, WORKER, App::new);
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.ExecutionMode.WORKER
import io.jooby.Jooby.runApp

fun main(args: Array<String>) {
  runApp(args, WORKER) {

    worker(Executors.newCachedThreadPool())
  
    get("/") {
      /** Safe to block from cached thread pool! */
      val result = ...;// Remote service, db call, etc..
      result
    }
  }
}
----

[NOTE]
====
While running in javadoc:ExecutionMode[WORKER] mode, Jooby internally does the dispatch call to the
worker executor. This is done per route, not globally.
====

==== Default

The javadoc:ExecutionMode[DEFAULT] execution mode is a mix between javadoc:ExecutionMode[WORKER] 
and javadoc:ExecutionMode[EVENT_LOOP] modes. This (as name implies) is the default execution mode in Jooby.

Jooby detects the route response type and determines which execution mode fits better.

If the response type is considered non-blocking, then it uses the *event loop*. Otherwise, it uses
the *worker executor*.

A response type is considered *non-blocking* when route handler produces:

- A `CompletableFuture` type
- A https://github.com/ReactiveX/RxJava[RxJava type]
- A https://projectreactor.io/[Reactor type]
- A https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html[Kotlin coroutine]

.Java
[source, java,role="primary"]
----
import static io.jooby.Jooby.runApp;

public class App extends Jooby {

  {
    get("/non-blocking", ctx -> {
      return CompletableFuture
          .supplyAsync(() -> "I'm non-blocking!")  // <1>    
    });
  
    get("/blocking", ctx -> {
      return "I'm blocking";                       // <2>
    });
  }

  public static void main(String[] args) {
    runApp(args, App::new);
  }
}
----

.Kotlin
[source, kotlin,role="secondary"]
----
import io.jooby.Jooby.runApp

fun main(args: Array<String>) {
  runApp(args) {
    get("/non-blocking") {
      CompletableFuture
          .supplyAsync { "I'm non-blocking!" }  // <1>    
    }
  
    get("/blocking") {
      "I'm blocking"                            // <2>
    }
  }
}
----

<1> `CompletableFuture` is a non-blocking type, run in *event loop*
<2> `String` is a blocking type, run in *worker executor*

[TIP]
====
You are free to use *non-blocking* types in all the other execution mode too. Non-blocking response
types are not specific to the **default mode** execution. All the *default mode* does with them is
to dispatch or not to a *worker executor*.
====

=== Worker Executor

This section described some details about the default *worker executor* provided by web server. The
worker executor is used when:

- Application mode was set to javadoc:ExecutionMode[WORKER]

- Application mode was set to javadoc:ExecutionMode[EVENT_LOOP] and there is a javadoc:Router[dispatch, java.lang.Runnable] call

Each web server provides a default *worker executor*:

- Netty: The javadoc:netty.Netty[text=Netty server] implementation multiply the number of available processors
(with a minimum of 2) by 8.

----
workerThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2) * 8
----

For example `8` cores gives us `64` worker threads.

- Undertow: The javadoc:utow.Utow[text=Undertow server] implementation multiply the number of available processors
(with a minimum of 2) by 8.

----
workerThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2) * 8
----

For example `8` cores gives us `64` worker threads.

- Jetty: The javadoc:jetty.Jetty[text=Jetty server] implementation uses the default configuration
with `200` worker threads.

These are sensible defaults suggested by the server implementation. If you need to increase/decrease
worker threads:

.Java
[source,java,role="primary"]
----
{
  configureServer(server -> {
    server.workerThreads(Number);
  });
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
{
  configureServer { server ->
    server.workerThreads(Number)
  }
}
---- 
