Erik Tjernlund
Erik Tjernlund

Reputation: 1983

Does SQL access block in the Play Framework?

I'm probably misunderstanding something fundamental about the Play Framework (2.x), but both the documentation about accessing an ordinary SQL database and the project samples doing so, does not seem to do this asynchronously.

There are no Promise<Result>, no Akka stuff etc.

Are you not blocking the main server thread if you do a database query with for example the ordinary MySQL JDBC driver? What am I missing?

Upvotes: 4

Views: 1063

Answers (2)

Martin Konicek
Martin Konicek

Reputation: 40934

Yes, the db driver blocks a thread waiting for the results from the database.

Even if you wrap the JDBC call in an Akka future like ico_ekito suggests, it will still block one server thread for the whole duration of the database request. Doing that potentially only executes the call on a different thread (depends on how Akka decides to execute it), but it will still block that thread.

The only proper way around this is to use a non-blocking database driver.

Btw, you can spot a blocking db driver quite easily. If its interface looks something like this:

ResultSet results = connection.execute(query);

It is definitely blocking. You can recognize a non-blocking API by methods returning Futures, Promises (which are Futures with a write side), or taking callbacks.

Also note that there is no "main" server thread (like the UI thread in browsers / desktop applications). There are just several threads handling requests.

For a deeper discussion have look a here.

Upvotes: 3

ndeverge
ndeverge

Reputation: 21564

AFAIK, if you are looking at the "computer-database" sample, you are totally right, it blocks the main thread since the actions are not executed asynchronously.

Here is an extract from the sample:

public static Result list(int page, String sortBy, String order, String filter) {
    return ok(
        list.render(
            Computer.page(page, 10, sortBy, order, filter),
            sortBy, order, filter
        )
    );
}

Here, the Computer.page() is doing some JDBC blocking calls.

If you'd want to do it asynchronously, you should enclose the database call in an async(F.Promise<Result>) call. Something like this:

public static Result list(int page, String sortBy, String order, String filter) {
    return async(
            Akka.future(
                new Callable<Result>() {
                  public Result call() {
                    return ok(
                        list.render(
                            Computer.page(page, 10, sortBy, order, filter),
                            sortBy, order, filter
                        )
                    );
                  }
                }
        )
    );

}

Upvotes: 3

Related Questions