Asyn c пользовательский метод в Vertx - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь создать свой собственный asyn c пользовательский метод в Vert.x, похожий на их код:

// call the external service
WebClient client = WebClient.create(vertx);

client.get(8080, "localhost:8080", "/fast").send(ar -> {
    if (ar.succeeded()) {

        HttpResponse<Buffer> response = ar.result();
        System.out.println("response.bodyAsString()" + response.bodyAsString());

    } else {
        System.out.println("Something went wrong " + ar.cause().getMessage());
    }
});

Когда вы запускаете этот код, поток спит без блокировки потока владельца, и предоставленный обработчик выполняется, когда конечная точка отвечает.

Я нашел способ сделать это с помощью: «executeBlocking», «createSharedWorkerExecutor.executeBlocking» и с использованием шины, но во всех них поток блокируется.

Я ищу способ сделать это, не блокируя поток контейнера, но я не нахожу его. Есть сообщение:

Как я могу реализовать пользовательскую асинхронную операцию в Vert.x?

Я пытался сделать это, но он также блокирует поток:

vertx.runOnContext(v -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
    }
    handler.handle(Future.succeededFuture("result"));
});

Приведенный выше код выполняется в том же потоке, но не работает одновременно, поэтому я предполагаю, что поток заблокирован.

Есть ли способ сделать это?

1 Ответ

1 голос
/ 31 января 2020

Способ, которым вы вызываете Thread.sleep(), отправит ваш текущий поток JVM в спящий режим, эффективно блокируя текущее событие vert.x l oop, которое выполняется в том же потоке. Это не идиоматический c способ в vert.x выполнить код блокировки.

Смотрите здесь: " Золотое правило - не блокируйте событие l oop".

Если вам нужно запустить код блокировки, например Thread.sleep(), вы должны реализовать этот код, используя рабочий вертикал . Рабочие версии используют потоки JVM из другого пула потоков и, следовательно, не блокируют событие l oop.

Первый пример кода, который вы опубликовали выше, не использует код блокировки, как вы правильно описали. Он использует идиоматический способ c с асинхронными неблокирующими обработчиками событий.

EDIT

См. Этот короткий пример того, как запустить очень простую рабочую фразу.

Код из класса WorkerVerticle никогда не заблокирует событие l oop. Вы делаете его рабочим во время развертывания вертикали, устанавливая правильный параметр, как показано в DeployerVerticle.

public class DeployerVerticle extends AbstractVerticle {

    @Override
    public void start() throws Exception {
        System.out.println("Main verticle has started, let's deploy another...");

        // Deploy it as a worker verticle
        vertx.deployVerticle("io.example.WorkerVerticle", 
                             new DeploymentOptions().setWorker(true));
    }
}


// ----

package io.example;
/**
 * An example of a worker verticle
 */
public class WorkerVerticle extends AbstractVerticle {

    @Override
    public void start() throws Exception {
        System.out.println("[Worker] Starting in " +
            Thread.currentThread().getName());

        // consume event bus messages sent to address "sample.data"
        // reply with incoming message transformed to upper case
        vertx.eventBus().<String>consumer("sample.data", message -> {

            Thread.sleep(1000); // will not block the event loop
                                // but only this verticle

            System.out.println("[Worker] Consuming data in " + 
                Thread.currentThread().getName());
            String body = message.body();
            message.reply(body.toUpperCase());
        });
    }
}
...