Quarkus 应用程序的 @Async 等价物是什么?
What is the @Async equivilant for Quarkus application?
在一个 class 中,我想调用一个方法,但不必等到该方法完成。通常在 spring 应用程序中,我会使用 @Async,但在 Quarkus 应用程序中该怎么做?
下面是一个简单的入门示例。在 'StartWork' class 中,'Work' 开始。 (我省略了工作接口,但您可以看到它的一个实现:WorkA)。调用 'work.do()' 后,startWork() 方法应该继续执行,而无需等待 work.do() 完成。
@ApplicationScoped
public class WorkA implements Work {
public void do() {
System.out.println("Starting work A.");
try {
Thread.sleep(1000l);
System.out.println("Finished work A.");
} catch(InterruptedException ex) {
System.out.println("My work got interrupted.");
}
}
}
@ApplicationScoped
public class StartWork {
@Inject
Work work;
public void startWork() {
work.do();
System.out.println("I dont' care when and if the work finished, but it has started.");
}
}
这是同一个例子,但现在我尝试使用 Mutiny:
@ApplicationScoped
public class WorkA implements Work {
public void do() {
Uni.createFrom().voidItem().invoke(Runnable -> {
System.out.println("Starting work A.");
try {
Thread.sleep(1000l);
System.out.println("Finished work A.");
} catch(InterruptedException ex) {
System.out.println("My work got interrupted.");
}
}
});
}
@ApplicationScoped
public class StartWork {
@Inject
Work work;
public void startWork() {
work.do();
System.out.println("I dont' care when and if the work finished, but it has started.");
}
}
当 运行 这个例子时,我没有看到正在打印的行。所以我猜匿名runnable没有被调用?
最小可重现产品:https://gitlab.com/rmvanderspek/quarkus-multithreading
工藤 Turing85 寻找答案。
事实证明,Quarkus 与 EventBus 一起用于异步操作。生产者已创建,但工作延迟,因此在消费者订阅此生产者之前不会被调用。
一个工作示例:https://gitlab.com/rmvanderspek/quarkus-multithreading
简而言之:
@ApplicationScoped
public class WorkA implements Work {
@Override
public void doWork() {
log.info("Do work");
Uni.createFrom()
.item(UUID::randomUUID)
.emitOn(Infrastructure.getDefaultWorkerPool())
.subscribe()
.with(this::worker, Throwable::printStackTrace);
}
private Uni<Void> worker(UUID uuid) {
log.info("Starting work: " + uuid);
try {
Thread.sleep((long) Math.random() * 1000);
} catch (InterruptedException ex) {
log.info("Could not finish work: " + uuid);
throw new RuntimeException(ex);
}
log.info("Finish work: {}.", uuid);
return Uni.createFrom().voidItem();
}
}
@ApplicationScoped
public class StartWork {
@Inject
Work work;
public void startWork() {
work.do();
System.out.println("I dont' care when and if the work finished, but it has started.");
}
}
在一个 class 中,我想调用一个方法,但不必等到该方法完成。通常在 spring 应用程序中,我会使用 @Async,但在 Quarkus 应用程序中该怎么做?
下面是一个简单的入门示例。在 'StartWork' class 中,'Work' 开始。 (我省略了工作接口,但您可以看到它的一个实现:WorkA)。调用 'work.do()' 后,startWork() 方法应该继续执行,而无需等待 work.do() 完成。
@ApplicationScoped
public class WorkA implements Work {
public void do() {
System.out.println("Starting work A.");
try {
Thread.sleep(1000l);
System.out.println("Finished work A.");
} catch(InterruptedException ex) {
System.out.println("My work got interrupted.");
}
}
}
@ApplicationScoped
public class StartWork {
@Inject
Work work;
public void startWork() {
work.do();
System.out.println("I dont' care when and if the work finished, but it has started.");
}
}
这是同一个例子,但现在我尝试使用 Mutiny:
@ApplicationScoped
public class WorkA implements Work {
public void do() {
Uni.createFrom().voidItem().invoke(Runnable -> {
System.out.println("Starting work A.");
try {
Thread.sleep(1000l);
System.out.println("Finished work A.");
} catch(InterruptedException ex) {
System.out.println("My work got interrupted.");
}
}
});
}
@ApplicationScoped
public class StartWork {
@Inject
Work work;
public void startWork() {
work.do();
System.out.println("I dont' care when and if the work finished, but it has started.");
}
}
当 运行 这个例子时,我没有看到正在打印的行。所以我猜匿名runnable没有被调用?
最小可重现产品:https://gitlab.com/rmvanderspek/quarkus-multithreading
工藤 Turing85 寻找答案。
事实证明,Quarkus 与 EventBus 一起用于异步操作。生产者已创建,但工作延迟,因此在消费者订阅此生产者之前不会被调用。
一个工作示例:https://gitlab.com/rmvanderspek/quarkus-multithreading
简而言之:
@ApplicationScoped
public class WorkA implements Work {
@Override
public void doWork() {
log.info("Do work");
Uni.createFrom()
.item(UUID::randomUUID)
.emitOn(Infrastructure.getDefaultWorkerPool())
.subscribe()
.with(this::worker, Throwable::printStackTrace);
}
private Uni<Void> worker(UUID uuid) {
log.info("Starting work: " + uuid);
try {
Thread.sleep((long) Math.random() * 1000);
} catch (InterruptedException ex) {
log.info("Could not finish work: " + uuid);
throw new RuntimeException(ex);
}
log.info("Finish work: {}.", uuid);
return Uni.createFrom().voidItem();
}
}
@ApplicationScoped
public class StartWork {
@Inject
Work work;
public void startWork() {
work.do();
System.out.println("I dont' care when and if the work finished, but it has started.");
}
}