---
schema_version: "1"
id: 887235fe4515e9661674fd117bd306317cdb90c3b333d266ca4025365d6f8bc2
title: Non-Blocking Operations
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-sdk/latest/non-blocking-operations.md
canonical_url: https://docs.mulesoft.com/mule-sdk/latest/non-blocking-operations
source_site: docs.mulesoft.com
content_type: documentation
content_hash: a831125945cc6dfc059be55434e4f41de1f24dfaca3429643677356a50d92649
description: MuleSoft Documentation Site
release: "1.13"
latest: true
---
---
product: Mule SDK
version: 1.13
is-latest-version: true
keywords: mule, sdk, operation, non, blocking, non-blocking
---

# Non-Blocking Operations

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

The Mule 4 execution engine is based on reactive streams. That means there’s top level support for
non-blocking operations. By default, all operations are blocking. As you probably noticed, the
semantics of all the operation examples you have seen [before](https://docs.mulesoft.com/mule-sdk/latest/operations) are inherently blocking:
the runtime invokes a method and gets a value in response. That is fine for operations that are more
CPU intensive than they are IO intensive, or for operations that consume APIs that cannot be
consumed in a non-blocking way, such as JDBC (the API that powers the Database connector).

HTTP is one of the protocols that does supports this. Being able to perform non-blocking HTTP
request is key for scalability of gateway proxies. Any connector consuming a REST API can also
benefit from this.

This simplified HTTP request example shows how the SDK allows you to develop non-blocking
operations:

```java
public void request(String url, @Connection HttpClient client, @Content InputStream body, (1)
    CompletionCallback<InputStream, HttpAttributes> callback ) { (2)
client.sendAsync(HttpRequest.builder()
          .uri(url)
          .method("POST")
          .entity(new InputStreamHttpEntity(body))
          .build()).whenComplete((response, e) -> {
        if (e != null) {
          callback.error(e); (4)
        } else {
          callback.success(Result.<InputStream, HttpAttributes>builder() (3)
                           .output(response.getEntity().getContent())
                           .attributes(toAttributes(response))
                           .build());
        }
      });
}
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>Unlike blocking operations, the return type is not specified through the method’s return type. Non-blocking operations always need to be specified through void methods.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>An operation becomes non-blocking when it has an argument of type <code>CompletionCallback</code>. This interface uses generics to specify the operation’s return type. The first generic is the type of the output payload, and the second one the type of the output attributes. These generics are mandatory.</td></tr><tr><td><i data-value="3"></i><b>3</b></td><td>The return value is passed through the <code>success(Result)</code> method of the <code>CompletionCallback</code>. See <a href="https://docs.mulesoft.com/mule-sdk/latest/result-object">Result</a> for more information on the <code>Result</code> object.</td></tr><tr><td><i data-value="4"></i><b>4</b></td><td>Non-blocking operations should not throw exceptions. Any errors should be channeled through the <code>error()</code> method in the callback.</td></tr></tbody></table>

> [!TIP] Notice that in this example, the `CompletionCallback` is being consumed from between an
> `HttpResponseCallback`. This second callback is provided by an `HttpClient` that supports
> asynchronous responses. As stated previously, in order to do non-blocking, you need to be
> consuming an API which allows that.

The result of this code is a non-blocking operation that returns an `InputStream` as payload and an
`HttpAttributes` object as message attributes.

## Void Operations

It is possible to have a void non-blocking operation. The use case for that is an IO operation that
does not return anything, such as writing to a file:

```java
public void write(String path, @Content byte[] bytes, CompletionCallback<Void, Void> callback) {
 writeAsync(result -> callback.success());
}
```

As you can see here, you can use Java’s `Void` type to indicate that the operation is void.

### Gotcha

You can also have an operation that sets the payload (but **NOT** the attributes) like this:

```java
public void foo(CompletionCallback<String, Void> callback) {
 ...
}
```

## Execution Types

Mule 4 now has a reactive execution engine. The runtime has a few global executors through which all
tasks are run.

To schedule tasks correctly, the runtime needs to know which kind of processing each operation is
going to perform. The different processing types are:

- CPU\_INTENSIVE: Intensive processing, such as a complex, time-consuming calculations or
  transformations. Note that the SDK will never infer a `CPU_INTENSIVE` type. See
  [Specifying Execution Types](#specify_execution_type).

- CPU\_LITE: Processing that neither blocks nor is CPU intensive, such as message passing,
  filtering, routing, or non-blocking IO.

- BLOCKING: Blocking processing that performs blocking IO operations, `Thread.sleep(long)`,
  `Lock.lock()`, or any other technique that blocks the current thread during processing. Although
  this type includes `Thread.sleep`, using it is a bad practice that you should avoid.

### Inferring Execution Types Automatically

The SDK follows these rules to make a best guess about the execution type so that you don’t have to
specify it explicitly:

- Operation requires connection and is blocking: `BLOCKING`

- Operation requires connection and is non-blocking: `CPU_LITE`

- None of the above: `CPU_LITE`

If the execution type to which your operation corresponds does not match the best guess, you should
specify the correct one. Failing to do so will negatively impact the performance of any app that
uses your module.

### Specifying Execution Types

You can manually specify an operation’s execution type through the `@Execution` annotation, for
example:

```java
@Execution(CPU_INTENSIVE)
public void computeFlightPlan() {
  ...
}
```
