code: public static VertxCompletableFuture<Void> runBlockingAsync(Context context, Runnable runnable) {
      Objects.requireNonNull(runnable);
      VertxCompletableFuture<Void> future = new VertxCompletableFuture<>(Objects.requireNonNull(context));
      context.<Void>executeBlocking(
          fut -> {
            try {
              runnable.run();
              fut.complete(null);
            } catch (Throwable e) {
              fut.fail(e);
            }
          },
          false,
          ar -> {
            if (ar.failed()) {
              future.completeExceptionally(ar.cause());
            } else {
              future.complete(ar.result());
            }
          }
      );
      return future;
    }
docs: Returns a new CompletableFuture that is asynchronously completed by a action running in the worker thread pool of
  Vert.x
  <p>
  This method is different from {@link CompletableFuture#runAsync(Runnable)} as it does not use a fork join
  executor, but the worker thread pool.
  
  @param context  the Vert.x context
  @param runnable the action, when its execution completes, it completes the returned CompletableFuture. If the
  execution throws an exception, the returned CompletableFuture is completed exceptionally.
  @return the new CompletableFuture