I am implementing a Quarkus server. On server start, a (never ending) background process should be started.
I know I can observe the start event with an @ApplicationScoped
bean which implements:
void onStart(@Observes StartupEvent ev)
.
But what is the best way to start a background process? Are there restrictions?
In J2EE one should not create Threads, but use ManagedExecutorService
or an EJB with a @Asynchronous
annotated method.
Is there something similar in Quarkus? I only found the scheduler annotations (which are nice, but I want to start a process only once at the beginning).
So can I just create threads? Or just put my infinite code in void onStart(@Observes StartupEvent ev)
?
Thank you
As in EJB you should not do such things with a background process. Such processes that are "out of control" of the framework cause most of time very annoying problems.
The answer is: It depends on what you want to do in that job.
If you want to execute tasks on a regular base you could use timers.
If you want to use it as an asynchronous worker, you can use a message queue.
Both is most easily done with the vert.x integration into Quarkus.
Use @ConsumeEvent to create a queue, use
@Inject
EventBus bus;
bus.send("Example message");
to send messages.
Use @Scheduled to work on regular jobs, like in this example.
If you need to permanently listen to some socket or file it is getting more difficult. Maybe the websockets will be helpful in this case.
The easiest way to start a worker thread is using Vertx#executeBlocking, like this:
@Inject
Vertx vertx;
void foo() {
vertx.<String>executeBlocking(promise -> {
// This code will be executed in a worker thread
System.out.println("Thread: " + Thread.currentThread());
promise.complete("Done");
}, asyncResult -> {
System.out.println(asyncResult.result()); // Done
});
}
If it will be a long running thread maybe it's a good idea not to use the default worker thread pool and create a new one:
...
@PostConstruct
void init() {
this.executor = vertx.createSharedWorkerExecutor("my-worker", 10);
}
void foo() {
executor.<String>executeBlocking(promise -> {
...
}
}
Other way of doing this is using a Verticle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With