I'm running a Quarkus Kafka producer inside a lambda. The thing is, that I want to block the main thread until all messages have been produced (and acknowledged) until I terminate the lambda execution. I see, that I can normally use the CompletionStage<Void> send(T msg);
of the microprofile Emitter, however, it only accepts a payload and not a Message, which I need to send the Metadata of the outgoing Kafka messages. Could you think of a way around that?
Asked
Active
Viewed 105 times
1

iliev951
- 33
- 4
1 Answers
0
You can add acknowledgement and negative-acknowledgement functions to a Message
, within which you can complete a future. Then, that future can be waited for after sending the message.
@Inject
@Channel("example-channel")
@OnOverflow(value = OnOverflow.Strategy.THROW_EXCEPTION)
Emitter<ObjectToSend> objectEmitter;
@Blocking
public void emitNewObject(ObjectToSend objectToSend) {
try {
CompletableFuture<Void> future = new CompletableFuture<>();
Message<ObjectToSend> message = buildMessage(objectToSend, future);
objectEmitter.send(message);
future.get();
} catch (InterruptedException | ExecutionException e) {
log.error("Error sending message", e);
throw new RuntimeException(e);
}
}
private Message<ObjectToSend> buildMessage(ObjectToSend objectToSend, CompletableFuture<Void> future) {
return Message.of(objectToSend)
.withAck(() -> {
future.complete(null);
return CompletableFuture.completedFuture(null);
}).withNack(reason -> {
future.completeExceptionally(reason);
return CompletableFuture.completedFuture(null);
});
}
In fact, the implementation of the emitter for the method that you mention in the question, does the same thing.

peterhuba
- 68
- 1
- 7