简体   繁体   中英

Vertx executeBlocking use event loop instead of worker thread

I come from concept one request = one thread and now i want to undertand the concept of event loop using Vertx . According to docs if we use blocking operation we should pass it to executeBlocking method.

Verticles use the Vert.x worker pool for executing blocking actions, i.e executeBlocking or worker verticle.

I have some questions related to this paragraph from http://vertx.io/docs/vertx-core/groovy/

This is my code:

public class JdbcVertx extends AbstractVerticle{
    public static void main(String[] args) {
        Vertx v = Vertx.vertx();
        v.deployVerticle(new JdbcVertx(),new DeploymentOptions().setWorkerPoolSize(10));


    }
    @Override
    public void start() throws Exception {
        JDBCClient client = JDBCClient.createNonShared(this.vertx, new JsonObject()
                                .put("url", "jdbc:postgresql://localhost:5432/test")
                                .put("user", "postgres")
                                .put("password", "pw")
                                .put("driver_class", "org.postgresql.Driver")
                                .put("max_pool_size", 30));

        this.vertx.createHttpServer()
                .requestHandler(r -> {
                    int i = (int) (Math.random() * 100);
                    System.out.println("Req id: " + i+ " "+Thread.currentThread().getName());
                    client.getConnection(handler -> {
                        if (handler.failed()) {
                            throw new RuntimeException(handler.cause());
                        } else {
                            final SQLConnection connection = handler.result();
                            this.vertx.executeBlocking(blockingCodeHandler->{
                            connection.execute(execute(), hndlr -> {
                                connection.close(closehndlr -> {
                                    if (closehndlr.failed()) {
                                        throw new RuntimeException(closehndlr.cause());
                                    } else {
                                        System.out.println("CON end: "+i+" "+Thread.currentThread().getName());
                                        r.response().putHeader("content-type", "text/html").end("Response: " + i);
                                    }
                                });
                            });
                            },false,as->{});
                        }
                    });
                }).listen(8080);
    }

    private String execute(){     
            return "insert into rubbish (name) values ('test')";

    }

I send 100 requests to http server this is output:

Req id: 45 vert.x-eventloop-thread-0
Req id: 22 vert.x-eventloop-thread-0
Req id: 96 vert.x-eventloop-thread-0
Req id: 85 vert.x-eventloop-thread-0
Req id: 33 vert.x-eventloop-thread-0
CON end: 22 vert.x-eventloop-thread-0
CON end: 33 vert.x-eventloop-thread-0
CON end: 45 vert.x-eventloop-thread-0
CON end: 85 vert.x-eventloop-thread-0

1) How event loop switched between requests (from output it firstly get some requests and then give them responses)?

2)I use executeBlocking method but how you can see code above use only event loop thread named vert.x-eventloop-thread-0

3)According to first question vertx event loop switched between request but if i change method execute to:

 private String execute(){ 
        Thread.sleep(3000);
            return "insert into rubbish (name) values ('test')";      
    }

It will stop the event loop until time out is not finished

Thank you in advance

1) You can look at EventLoop this way: each time you provide a handler, it's another function that is put on a queue of sort.

When your first requests come in, it may look something like this requestHandler (R1) requestHandler (R2)

Then EventLoop wil l pop first element in the queue, and put it's result back on the queue: requestHandler (R2) getConnection (R1)

Then third request may come in, while we popped requestHandler (R2) : getConnection (R1) requestHandler (R3) getConnection (R2)

And that repeats, hence Loop

2) You don't do anything in your blocking handler, actually. Add some large loop before if (closehndlr.failed()) { , and you'll see warnings.

What happens now is that you're doing async->sync->async , and your sync is basically 0ms.

You can see this with the following code:

vertx.setPeriodic(1000, h -> {
        System.out.println("Periodic on " + Thread.currentThread().getName());
       vertx.executeBlocking(f -> {
           System.out.println("Future on " + Thread.currentThread().getName());
           f.complete();
       }, r -> {
           System.out.println("Result on " + Thread.currentThread().getName());
       });
    });

Prints:

Periodic on vert.x-eventloop-thread-0
Future on vert.x-worker-thread-3
Result on vert.x-eventloop-thread-0
Periodic on vert.x-eventloop-thread-0
Future on vert.x-worker-thread-4
Result on vert.x-eventloop-thread-0

3) Don't use Thread.sleep(3000) :) By doing that, you just ask the EventLoop to stop for 3s. You've also should have seen warning regarding that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM